数据结构回顾-------单链表

单链表,用指针来实现的线性表

为了方便操作,我们定义一个头指针来操作链表

结构体为Node      一个整型data,一个Node指针next指向下一个节点

封装类为LinkList    链表的各个操作具体看类的函数即可。

/*
 * 单链表的实现 
 *为了看起来简单点,这里用int类型作为链表的数据类型 
*/

#include<iostream>

using namespace std;

//定义一个结构体。data存贮数据,next指针指向下一个数据 
struct Node
{
	int data;
	Node * next;
} ;
 
class LinkList
{
	public:
		
		LinkList()   //无参的构造函数,构造一个空的链表 
		{
			first = new Node;
			first->next = NULL; 
		} 
		
		//有参构造函数,我把尾插法和头插法建立链表都放里面了 
		LinkList(int a[],int n) 
		{
			
			/*
			*	
			//头插法建立单链表 ---我不喜欢用这个,注释掉 
			
			first = new Node;//初始化指针 
			first->next = NULL;
			for(int i = 0;i < n;i++) 
			{
				Node *s = new Node;
				s->data = a[i];
				
				s->next = first->next;  //节点s的指针域指向头指针的下一个数据体
				first->next = s;        //头指针的指针域指向s。   
				//这两行代码实现了将一个节点s插入到头指针的下一个节点 
			} 
			*/ 
			
			/*
			*尾插法建立单链表 
			*/
			first = new Node;//生成头节点
			Node *r = first;//初始化尾指针
			for(int i = 0;i < n;i++)
			{
				//创建一个节点 
				Node *s = new Node;
				s->data = a[i];
				
				r->next = s; //尾指针的下一个节点指向是s 
				r = s;        //尾指针r移到s节点 
			} 
			r->next = NULL;//单链表创建完毕,将终端节点指针域置空 
		 
		} 
	
		//析构函数,释放资源 
		~LinkList()
		{
			while(first != NULL)
			{
				Node *q = first;//暂存被释放的节点 
				first = first->next;//first节点往后移 
				delete q;
			}
		}
	
		int Getlength()     //求单表的长度 
		{
			Node *p = first->next;//p指向链表第一个非空节点(不是头结点),操作链表 
			int count = 0;
			
			while(p != NULL)
			{
				p = p->next;
				count++;
			} 
			return count;
		} 
	
		int Get(int i )  //按位查找,在单链表中查找第i个元素
		{
			Node *p = first->next;
			int count = 1;
			while(p != NULL && count < i)
			{
				p = p->next;
				count++;
			} 
			if(p == NULL)
				throw "位置不正确";
			else
				return p->data;
		}
		 
	
		int Locate(int x)  //按值查找,查找单链表中值为x的元素序号
		{
			Node *p = first->next;
			int count = 1;
			//循环遍历单链表,如果找到相等数据,返回count 
			while(p != NULL)
			{
				if(p->data == x)
					return count;
				p = p->next;
				count++;
			}
			//退出循环代表查找失败,链表中没有这个数据 
			return 0;
		}
	
		void Insert(int i ,int x)  //插入操作,在单链表中第i个位置插入值为x的元素
		{
			Node *p = first;//工作指针应该指向头结点
			int count = 0;
			//循环,工作节点p找到第i个节点的位置 
			while(p != NULL && count < i-1)
			{
				p = p->next;
				count++;
			} 
			if(p == NULL)
				throw "位置不正确";
			else
			{
				//建立新节点 
				Node *s = new Node;
				s->data = x;
				//将节点s插入到节点p之后 
				s->next = p->next;
				p->next = s;
			}
		} 
	
		int Delete(int i)   //删除操作,删除表中的第i个元素
		{
			Node *p = first;
			int count = 0;
			//工作指针找到i的前一个节点位置 
			while(p != NULL && count < i-1)
			{
				p = p->next;
				count++;
			}
			if(p == NULL || p->next == NULL) //如果节点p不存在或者p的后继节点不存在
				throw "位置不正确";
			else
			{
				Node *q = p->next; //暂存被删除节点 
				int x = q->data;
				p->next = q->next;//将第i个节点从链表中摘除
				delete q;
				return x; 
			} 
		}
	
		void PrintList()        //遍历操作,按序号输入出各个元素
		{
			Node *p = first->next;
			while(p != NULL)
			{
				cout<<p->data<<" ";
				p = p->next;
			}
			cout<<endl;
		}
	
	private:
		Node *first; //头指针 
		 
} ;

int main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,0};
	int n = 10;
	LinkList ll(a,n);
	
	cout<<"第5个数据是:"<<ll.Get(5)<<endl;
	cout<<"链表的长度时:"<<ll.Getlength()<<endl;
	cout<<"值为6的数据所在的位置是:"<<ll.Locate(6)<<endl;
	cout<<"遍历插入前的链表:";
	ll.PrintList();
	cout<<"往第7个位置插入数据12";
	ll.Insert(7,12);
	cout<<"遍历插入后的链表:";
	ll.PrintList();
	cout<<"删除第三个数据后的链表:";
	ll.Delete(3); 
	ll.PrintList(); 
	
	return 0;


测试结果:


还可以通过控制台数据数据,然后将用户手动输入的数据存放在链表中,这个实现起来应该不难,稍微修改一下代码就可以啦

猜你喜欢

转载自blog.csdn.net/wanmingJKing/article/details/80708700