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

版权声明:本文为博主原创文章,未经许可,不得转载! https://blog.csdn.net/bin_ge_love/article/details/51658887
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
以“结点的序列”表示线性表称作线性链表(单链表)
单链表是链式存取的结构,为找第 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;
}

运行截图:


猜你喜欢

转载自blog.csdn.net/bin_ge_love/article/details/51658887