单链表的增、删、查、改、逆置、排序

来源:互联网 发布:部落冲突亡灵升级数据 编辑:程序博客网 时间:2024/04/26 03:20
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
以“结点的序列”表示线性表称作线性链表(单链表)
单链表是链式存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。
因此,查找第 i 个数据元素的基本操作为:移动指针,比较 j 和 i
链表的具体存储表示为:
① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))
注意:
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。
下边是具体的实现代码:
LinkList.h
#include<iostream>#include<assert.h>using namespace std;template<class T>class LinkList;//  复合类:在Node类中定义友元的方式,使List类可以访问结点的私有成员template <class T>class LinkNode{friend class LinkList<T>;public:LinkNode(T x ) {_data = x;_next = NULL;}private:T _data;LinkNode<T>  *_next;};template <class T>class LinkList{public:LinkList(){_head = NULL;}void PushBack(const T& x);//尾插void PopBack();//尾删void PushFront(const T& x);void PopFront();int Length();//求表长LinkNode<T>* Find(const T& x);void Insert_pos(size_t pos, const T& x);void Insert_val(const T& n, const T& x);LinkNode<T> * Reverse();       //逆置void Delete_pos(size_t pos);//按位置删除void Delete_val(const T& x);//按值删除void Sort();//排序LinkNode<T>* ClearLinkList();       //清除单链表void Print()// 打印{LinkNode<T>  *tmp = _head;while (tmp != NULL){cout << tmp->_data << "->";tmp = tmp->_next;}cout << "NULL" << endl;}public:LinkNode<T>* _CreateNode(const T& x)//创建结点{LinkNode<T>* tmp = new LinkNode<T>(x);return tmp;}void clear(LinkNode<T>* &cur){cur->_next = NULL;delete  cur;cur = NULL;}private:LinkNode<T> * _head;};template<class T>int LinkList<T> ::Length()//求表长{int len = 0;if (_head == NULL){cout << "The Length of List is:" << "0" << endl;return 0;}else{LinkNode<T> * begin = _head;while (begin != NULL){begin = begin->_next;len++;}}cout << "The Length of List is >>>:  " << len << endl;return len;}template <class T>void LinkList<T> ::PushBack(const T& x)//尾插{if (_head == NULL){_head = _CreateNode(x);}else{LinkNode<T> * end = _head;while (end->_next != NULL){end = end->_next;}end->_next = _CreateNode(x);}}template <class T>void LinkList<T> :: PopBack()//尾删{if (_head == NULL){cout << "List is empty!!!" << endl;return;}else if (_head->_next == NULL){clear(_head);}else{LinkNode<T> * prev = _head;LinkNode<T> * end = _head;while (end->_next != NULL){prev = end;end = end->_next;}prev->_next = NULL;clear(end);}}template <class T>void LinkList<T> :: PushFront(const T& x)//头插{if (_head == NULL){_head = _CreateNode(x);}else{LinkNode<T>  * prev = _CreateNode(x);prev->_next = _head;_head = prev;}}template <class T>void LinkList<T> ::PopFront(){if (_head == NULL){cout << "List is empty!!!" << endl;return;}else if (_head->_next == NULL){clear(_head);}else{LinkNode<T> * tmp = _head;_head = _head->_next;clear(tmp);tmp = NULL;}}template <class T>LinkNode<T>* LinkList<T> ::Find (const T& x)//查找{if (_head == NULL){cout << "List is empty,not found!!!" << endl;return NULL;}else{LinkNode<T> * n = _head ;while (n->_next != NULL && n->_data != x ){n = n->_next;if (n->_data == x){cout << "The data of your find is :" << n->_data << endl;return n;}}}cout << "There is no this data in the List!!!" << endl;return NULL;}template <class T>void LinkList<T> ::Insert_pos(size_t pos,const T& x)//在第n个后面插入{int len = Length();if (pos <= len){if (_head == NULL){cout << "List is empty!!!" << endl;return;}else{LinkNode<T> * begin = _head;LinkNode<T> * tmp = _CreateNode(x);while (--pos){if (begin->_next != NULL){begin = begin->_next;}}tmp->_next = begin->_next;begin->_next = tmp;}}else{cout << "Input Error!!!" << endl;}}template <class T>void LinkList<T> ::Insert_val(const T& m ,const T& x)//按值插入{if (_head == NULL){cout << "List is empty!!!" << endl;return;}else{LinkNode<T> * n =  Find(m);if (n != NULL){LinkNode<T> * tmp = _CreateNode(x);tmp->_next = n->_next;n->_next = tmp;}cout << "Input Error!!!" << endl;}}template <class T>void LinkList<T> ::Delete_pos(size_t pos)//删除第n个{int len = Length();if (pos <= len){if (_head == NULL){cout << "List is empty!!!" << endl;return;}else if (_head->_next == NULL){clear(_head);}else{LinkNode<T> * begin = _head->_next;LinkNode<T> * tmp = _head;pos = pos - 1;while (--pos){if (begin->_next != NULL){begin = begin->_next;tmp = tmp->_next;}}tmp->_next = begin->_next;begin->_next = tmp;}}else{cout << "Input Error!!!" << endl;}}template <class T>void LinkList<T> ::Delete_val(const T& x)//按值删除{if (_head == NULL){cout << "List is empty!!!" << endl;return;}else if (_head->_next == NULL && _head->_data == x){clear(_head);return;}else{if (_head->_data == x){PopFront();return;}else{LinkNode<T> * n = Find(x);if (n != NULL){LinkNode<T> * begin = _head;while (n != NULL && begin->_next != n && begin->_next != NULL){begin = begin->_next;}begin->_next = n->_next;clear(n);return;}}}return;}template <class T>LinkNode<T>* LinkList <T> ::Reverse()// 逆置{if (_head == NULL || _head->_next == NULL)//为空{return NULL;}else//非空{LinkNode<T> * Newhead = _head;LinkNode<T> * begin = _head->_next;LinkNode<T> *tmp = NULL;_head->_next = NULL;while (begin != NULL){tmp = begin;begin = begin->_next;tmp->_next = Newhead;Newhead = tmp;}_head = Newhead;}}template<class T>LinkNode<T>* LinkList<T>:: ClearLinkList()       //清除单链表{int len = Length();if (_head == NULL){cout << "The LinkList is empty!!!" << endl;return NULL;}LinkNode<T>* cur = _head;while (len--){PopBack();}_head = NULL;return _head;}template<class T>void LinkList<T>:: Sort(){LinkNode<T>* slow = _head;LinkNode<T>* fast = _head;if (_head == NULL || _head->_next == NULL){return;}while (slow->_next){fast = slow->_next;while (fast){if (slow->_data > fast->_data){T tmp = slow->_data;slow->_data = fast->_data;fast->_data = tmp;}fast = fast->_next;}slow = slow->_next;}}

测试代码:
#include "LinkList.h"void Test1(){LinkList<int> a;a.PushBack(1);a.PushBack(2);a.PushBack(3);a.Print();a.PopBack();a.Print();a.PopBack();a.Print();a.PopBack();a.Print();a.PushFront(1);a.PushFront(4);a.PushFront(3);a.PushFront(2);a.Print();a.PopFront();a.Print();a.PopFront();a.Print();a.PopFront();a.Print();a.PopFront();a.Print();a.PopFront();}void Test2(){LinkList<int> l;l.PushBack(1);l.PushBack(2);l.PushBack(3);l.Print();l.Insert_val(3, 5);l.Insert_pos(4, 7);l.Print();l.Reverse();l.Print();l.Delete_pos(3);l.Print();l.Delete_val(7);l.Print();l.Length();}//void main()//{////Test1();////Test2();////}int main(){//Test1();//Test2();//Test3();//Test4();//template <class T, int DefaultCapacity = 10 >LinkList<int> mylist;int select = 1;int Item;int pos;flag:cout << endl << endl;;cout << "* * * * * * * welcome to use LinkList* * * * * * * *" << endl;void Menu();{cout << "*1. PushBack2. PushFront      *" << endl;cout << "*3. Print4. PopBack        *" << endl;cout << "*5. PopFront6. Insert_pos     *" << endl;cout << "*7. Insert_val        8. Delete_pos     *" << endl;cout << "*9. Delete_val        10.Find           *" << endl;cout << "*11. length12.clear  *" << endl;cout << "*13. reverse14.sort  *" << endl;cout << "*0.exit                      *" << endl;cout << "*              *" << endl;cout << "*       Please select:          *" << endl;cout << "* * * * * * * * * * * * * * * * * * * * * * * * * *" << endl;}while (select){cin >> select;switch (select){case 1:cout << "请输入要后插的值(-1结束):>";while (cin >> Item, Item != -1){mylist.PushBack(Item);}break;case 2:cout << "请输入要头插的值(-1结束):>";while (cin >> Item, Item != -1){mylist.PushFront(Item);}break;case 3:mylist.Print();break;case 4:mylist.PopBack();break;case 5:mylist.PopFront();break;case 6:cout << "请输入要插入的位置:>";cin >> pos;cout << "请输入要插入的值:>";cin >> Item;mylist.Insert_pos(pos, Item);break;case 7:cout << "请输入要在i插入的值:>";cin >> pos;cout << "请输入要插入的值x:";cin >> Item;mylist.Insert_val(pos, Item);break;break;case 8:cout << "请输入要删除的位置:>";cin >> pos;mylist.Delete_pos(pos);break;case 9:cout << "请输入要删除的值:>";cin >> Item;mylist.Delete_val(Item);break;case 10:cout << "请输入要查找的值:>";cin >> Item;mylist.Find(Item);break;case 11:mylist.Length();break;case 12:mylist.ClearLinkList();break;case 13:mylist.Reverse();break;case 14:mylist.Sort();break;case 0:exit(0);default:break;}cout << endl;goto flag;}return 0;}

运行截图:


0 0
原创粉丝点击