以“结点的序列”表示线性表称作线性链表(单链表)
单链表是链式存取的结构,为找第 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. PushBack 2. PushFront *" << endl;
cout << " * 3. Print 4. PopBack *" << endl;
cout << " * 5. PopFront 6. Insert_pos *" << endl;
cout << " * 7. Insert_val 8. Delete_pos *" << endl;
cout << " * 9. Delete_val 10.Find *" << endl;
cout << " * 11. length 12.clear *" << endl;
cout << " * 13. reverse 14.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;
}
运行截图: