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/C++]_[链表的最佳创建方式]
- [数据结构]_[C/C++]_[链表的最佳创建方式]
- 【数据结构 笔记00】C++链表的创建与操作
- C++数据结构---链表(链表节点创建)
- [C++]数据结构:链表二叉树的创建与四种遍历方式
- c++图书编号与价格 链表的创建及显示
- 【C++/数据结构】循环链表的基本操作
- 【数据结构】C语言实现链表的创建及遍历链表
- 数据结构:C++链表类及一元多项式的实现时遇到的困难
- 郝斌数据结构(1)----数据结构基本分类和链表创建
- 数据结构--链表(C++)
- C语言创建和操作单链表数据结构的实例教程
- 数据结构:链表 C++
- 数据结构单链表创建(头插法,尾插法)java/c/c++
- 经典算法与数据结构的c++实现——带头结点的单链表
- 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现
- c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)
- C++数据结构--循环链表的应用--解决约瑟夫问题
- 复习(数据结构):链表:c++:stl
- C++实现数据结构中的单链表