您的位置:首页 > 理论基础 > 数据结构算法

C++数据结构---链表(链表创建)

2017-08-14 00:02 453 查看

链表

是比较重要的一种数据结构,它的有点在于:插入和删除操作。

与vector不同,list插入和删除不需要移动其余元素,而vector在中间插入时,需要将后面的元素依次向后移动,时间复杂度与待移动的元素有关,可见,元素越多,消耗的时间越多。而list插入元素时,只需要将改变“链接线”,即pred和succ即可,不需要对元素进行移动。删除操作同上。

但是,list的缺点也是很明显的:不同于vector的按下标索引,list是一步一步的从头到尾进行遍历,直到找到该元素为止。

所以:

对于链表:适用于要经常插入与删除,而对于随机访问操作较少的情况

对于vector:适用于随机访问操作较多的情况

本文附上链表创建的整个代码(重载了vector的按下标索引符号[]),包括自己写的链表节点创建的头文件(节点创建可以看C++数据结构—链表(链表节点创建)

链表创建代码如下:

#pragma once
#ifndef LIST_HH
#define LIST_HH
#include<iostream>
#include"ListNode.h"
using namespace std;
template <typename T> class List {
private:
int _size;
ListNodePosi(T) header;
ListNodePosi(T) trailer;
public:
List() { init(); }
~List();
void init();//初始化节点
void clear();//清除链表

int size() { return _size;}//链表的长度

T& operator[](int r)const;//[]操作符重载

T remove(ListNodePosi(T) p);//删除结点

void deduplicate();//去重复结点(无序序列)

//**********排序操作**********//
void insertsort();//插入排序
void selectionSort(ListNodePosi(T) p, int n);//选择排序
void sort(ListNodePosi(T) p, int n);
void sort() { sort(first(), _size); }
//***************************//
ListNodePosi(T) first() const { return header->succ; }//除了头结点的首结点,这里假设链表的第一个结点前面有个虚拟的head结点
ListNodePosi(T) last() const { return trailer->pred; }//同上
ListNodePosi(T) find(T const& _Val, int n, ListNodePosi(T) p);

//**********插入操作**********//
ListNodePosi(T) insertAsFirst(T const& _Val);
ListNodePosi(T) insertAsLast(T const& _Val);
ListNodePosi(T) insertAsBefore(ListNodePosi(T) p, T const& _Val);
ListNodePosi(T) insertAsAfter(ListNodePosi(T) p, T const& _Val);
ListNodePosi(T) insertAsSucc(T const& _Val);
ListNodePosi(T) insertAsPred(T const& _Val);
//***************************//

ListNodePosi(T) search(T const& _Val, int n, ListNodePosi(T) p);    //搜索操作
ListNodePosi(T) getNode(T const& _Val);//获取当前值的节点位置
ListNodePosi(T) selectmax(ListNodePosi(T) p, int n);
int max_data() { return (selectmax(first(),_size)->data);}
};

template <typename T>
void List<T>::init()
{
header = new ListNode<T>;
trailer = new ListNode<T>;
header->succ = trailer;
header->pred = NULL;
trailer->succ = NULL;
trailer->pred = header;
_size = 0;
}

template <typename T>
T& List<T>::operator[](int r) const
{
ListNodePosi(T) p = first();
while (0 < r--) p = p->succ;
return p->data;
}
template <typename T>
ListNodePosi(T) List<T>::find(T const& _Val, int n, ListNodePosi(T) p)
{
while (0 < n--)
if (_Val == (p = p->pred)->data) return p;
return NULL;
}

template <typename T>
ListNodePosi(T) List<T>::getNode(T const& _Val)
{
ListNodePosi(T) p = find(_Val,_size,last());
return p;
}
template <typename T>
ListNodePosi(T) List<T>::insertAsFirst(T const& _Val)
{
_size++; return header->insertAsSucc(_Val);
}
template <typename T>
ListNodePosi(T) List<T>::insertAsLast(T const& _Val)
{
_size++; return trailer->insertAsPred(_Val);
}
template <typename T>
ListNodePosi(T) List<T>::insertAsBefore(ListNodePosi(T) p,T const& _Val)
{
_size++; return p->insertAsPred(_Val);
}
template <typename T>
ListNodePosi(T) List<T>::insertAsAfter(ListNodePosi(T) p,T const& _Val)
{
_size++; return p->insertAsSucc(_Val);
}
template <typename T>
ListNodePosi(T) ListNode<T>::insertAsPred(T const& _Val)
{
ListNode
4000
Posi(T) x = new ListNode(_Val, pred, this);
pred->succ = x; pred = x;
return x;
}
template <typename T>
ListNodePosi(T) ListNode<T>::insertAsSucc(T const& _Val)
{
ListNodePosi(T) y = new ListNode(_Val, this, succ);
succ->pred = y; succ= y;
return y;
}

template <typename T>
T List<T>::remove(ListNodePosi(T) p)
{
T _Val = p -> data;
p->pred->succ = p->succ;//待删除节点p的前驱的后继给p的后继
p->succ->pred = p->pred;//p的后继的前驱给p的p的前驱
delete p;
_size--;
return _Val;
}
template <typename T> List<T>::~List()
{
clear(); delete header; delete trailer;
}
template <typename T>
void List<T>::clear()
{
while (0 < _size)
remove(header->succ);
}

template <typename T>
void List<T>::deduplicate()
{
if (_size < 2) return;
ListNodePosi(T) p = first(); int r = 1;
while (trailer != (p = p->succ))
{
ListNodePosi(T) q = find(p->data, r, p);
q ? remove(q) : r++;
}
}

template <typename T>
ListNodePosi(T) List<T>::search(T const& _Val, int n, ListNodePosi(T) p)
{
while (0 <= n--)
{
if ((p = p->pred)->data <= _Val) break;
}
return p;
}

template <typename T>
ListNodePosi(T) List<T>::selectmax(ListNodePosi(T) p,int n)
{
ListNodePosi(T) max = p;
ListNodePosi(T) cur = p;
for (ListNodePosi(T) cur = p; n>0; n--)
{
if (max->data < cur->data) max = cur;
cur = cur->succ;
}
return max;
}

template <typename T>
void List<T>::insertsort()
{
printf("InsertSort ...\n");
ListNodePosi(T) q = first();
for (int i = 0; i < _size; i++)
{
insertAsAfter(search(q->data, i, q), q->data);
q = q->succ;
remove(q->pred);
}
}

template <typename T>
void List<T>::selectionSort(ListNodePosi(T) p, int n) {
printf("SelectionSort ...\n");
ListNodePosi(T) head = p->pred; ListNodePosi(T) tail = p;
for (int i = 0; i < n; i++) tail = tail->succ; //
while (1 < n) {
ListNodePosi(T) max = selectmax(head->succ, n); //
insertAsBefore(tail, remove(max)); //将其移至无序区间末尾(作为有序区间新的首元素)
tail = tail->pred; n--;
}
}

template <typename T> void List<T>::sort(ListNodePosi(T) p, int n) { //列表区间排序
switch (rand() % 2) { //随机选取排序算法
case 1:  insertsort(); break;
case 2:  selectionSort(p, n); break;
}
}
#endif // !LIST_HH


测试代码:

#include<iostream>
#include"ListNode.h"
#include"List.h"
using namespace std;

int main()
{

List<int> L;
printf("*****请输入你要创建的结点(输入完按回车继续)*******\n");
int a;
while (cin>>a&&a!='q') {
L.insertAsLast(a);
}

printf("*******原数组为*******\n");
for (int i = 0; i < L.size(); i++)
cout << L[i] << " ";
printf("\n");

printf("*******链表长度为***********\n");
cout << L.size() << endl;

printf("*******排序并去重复后的数组为*******\n");
L.sort();
L.deduplicate();
for (int i = 0; i < L.size(); i++)
cout << L[i] << " ";
cout << endl;

printf("*******最大数为*******\n");
cout << L.max_data() << endl;

printf("*******链表清除后的链表长度为***********\n");
L.clear();
cout << L.size() << endl;
system("pause");
return 0;
}


结果如图所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 数据结构 链表