单链表操作

149 阅读4分钟

单链表操作

准备工作:

a. 建立单链表结构类型

typedef struct Lnode{
	int data;
	Lnode *next;
}Lnode,*LinkList;

b. 准备一个“show()”函数用来展示单链表

//展示函数
void show(LinkList &T){
	Lnode* p;
	p = T->next;
	if(!p){
		cout<<"链表为空"<<endl;;
	}else{
		while(p){
		cout<<p->data<<endl;;
		p =p->next;
	 }
	}
}

操作1. 单链表的创建

a. 头插法创建单链表

void CreateList_H(LinkList &T){   //一个指针解决问题 
	T = new Lnode;   
	T->next = NULL;   //创建一个带头结点的空链表 
	Lnode *p;   //创建一个指针用来开辟结点 
	p = new Lnode;   //do while循环,所以在while外给p开辟空间 
	while(cin>>p->data){  //输入"#"结束输入 
		p->next = T->next;   
		T->next = p;   //实质是把p夹在T和T->next中间 
		p = new Lnode;	 //把wile外的语句再执行一次 
	}
}

b. 尾插法创建单链表

void CreateList_R(LinkList &T){   //两个指针解决问题 
	T = new Lnode;    //头节点 
	Lnode *r=T;   //尾指针指向头节点 
	Lnode *p;   //p指针用来开辟新节点 
	p = new Lnode;   
	p->next= NULL;   //do while中的do 
	while(cin>>p->data){
		r->next= p;   //尾指针连接p指针 
		r= p;   //后移一位 
		p = new Lnode;
		p->next= NULL;  //do while 中的do 
	}
}

操作2. 单链表的清空和销毁

//单链表的清空
void ClearList(LinkList &T){
	Lnode *p = T->next;  //从首元结点开始删除 ,先让p指向首元节点 
	Lnode *q;   //p是“先锋”,他去负责移位,q是“执行者”,负责删除东西 
	while(p){
		q = p;   //“先锋”告诉“执行者” 要删啥 
		p = p->next;   //“先锋”去寻找下一个目标 
		delete(q);   //“执行者”删除东西 
		
	}
	T->next = NULL;   //善后工作,使得此链表符合空链表的特征 
	cout<<"SUCCESS!!!"<<endl;
}

//单链表的销毁
void DestroyList(LinkList &T){   //销毁操作就是把清空操作的q指针换成头指针T(既然都要销毁了,不用白不用) 
	Lnode *p = T;                //而且单链表销毁操作连头节点都不留,这一点和清空操作做区分 
	while(T){
		p = T;
		T = T->next;
		delete(p);
	}
	cout<<"SUCCESS!!!"<<endl;	
} 

操作3. 求单链表长度

//求单链表长度
void ListLength(LinkList &T){   //创一个指针从受源节点往后数,数到一个i++ 
	Lnode *p = T->next;
	int i = 0;
	while(p){
		i++;
		p = p->next;
	}
	cout<<"单链表长度为:"<<i<<endl;
}

操作4. 按值查找和按位置查找

//按位置查找 
int GetElem(LinkList &T,int i,int &e){
	Lnode* p = T->next;    //创建一个指针指向首元节点 
	int j = 1;   //计数器 
	while(j<i){
		p=p->next;  //向后查找 
		j++;   //计数器加一 
	}
	e = p->data;   //保存查找的数据 
	cout<<e<<endl;
	return 0;
}

//按值查找,返回其序号 
int LocateList(LinkList T,int e){
	Lnode *p = T->next;
	int i= 1;
	while(p&&p->data!=e){
		p = p->next;
		i++;
	} 
	cout<<"值为:"<<e<<"的结点为第"<<i<<"个结点"<<endl; 
	return 0;
}

操作5. 单链表的插入

//单链表的插入
int InsertList(LinkList &T,int i,int &e){
	Lnode *p = T;   //先建立一个指针指向头节点,准备向后移动i-1次 
	for(int j=1;j<i;j++){   //p指针向后移动i-1次 (插入位置是1就移动0次,插入位置是2就移动1次) 
		p = p->next;
	}
	Lnode *q;     //创建q指针用来开辟一个新的结点 
	q = new Lnode;
	q->data = e;   //把e存入新结点 
	q->next = p->next;   //连接新节点的屁股 
	p->next = q;   //连接新节点的头 
	cout<<"单链表插入成功"<<endl; 
	return 1;
} 

操作6. 单链表的删除

//单链表的删除
int deleteLnode(LinkList &T,int i,int &e){
	Lnode *p = T;   //创建一个指针指向头节点 
	for(int j=1;j<i;j++){   //for循环作用:让p指向要删除节点的前一个结点 
		p = p->next;
	}
	e = p->next->data;   //p为要删除的节点的前一个,所以p的后一个结点的data就是目标内容 
	p->next = p->next->next;   //把链表连起来,不能因为删除了一个结点就使链表整个断开 
	cout<<"已删除"<<e<<endl;
	return 0; 
}

完整操作:

#include<bits/stdc++.h>
using namespace std;

typedef struct Lnode{
	int data;
	Lnode *next;
}Lnode,*LinkList;

void CreateList_H(LinkList &T);
void show(LinkList &T);
void CreateList_R(LinkList &T);
void ClearList(LinkList &T);
void DestroyList(LinkList &T);
void ListLength(LinkList &T);
int GetElem(LinkList &T,int i,int &e);
int LocateList(LinkList T,int e);
int InsertList(LinkList &T,int i,int &e);
int deleteLnode(LinkList &T,int i,int &e);
 
int main(){
	LinkList L;
	int k;
	int m;
	int h = 1919810;
//	CreateList_H(L);
//	show(L);
	CreateList_R(L);   //两种链表的建立方式不能同时运行,不然第二个cin不能输入东西 
	show(L);
//	ClearList(L);
//	show(L);
//	DestroyList(L);
//	show(L);
	ListLength(L);
//	GetElem(L,2,k);
	LocateList(L,114514);
	InsertList(L,7,h);
	show(L);
	deleteLnode(L,7,m);
	return 0;
}

//展示函数
void show(LinkList &T){
	Lnode* p;
	p = T->next;
	if(!p){
		cout<<"链表为空"<<endl;;
	}else{
		while(p){
		cout<<p->data<<endl;;
		p =p->next;
	 }
	}
}

//头插法建立单链表
void CreateList_H(LinkList &T){   //一个指针解决问题 
	T = new Lnode;   
	T->next = NULL;   //创建一个带头结点的空链表 
	Lnode *p;   //创建一个指针用来开辟结点 
	p = new Lnode;   //do while循环,所以在while外给p开辟空间 
	while(cin>>p->data){  //输入"#"结束输入 
		p->next = T->next;   
		T->next = p;   //实质是把p夹在T和T->next中间 
		p = new Lnode;	 //把wile外的语句再执行一次 
	}
}
//尾插法建立单链表 
void CreateList_R(LinkList &T){   //两个指针解决问题 
	T = new Lnode;    //头节点 
	Lnode *r=T;   //尾指针指向头节点 
	Lnode *p;   //p指针用来开辟新节点 
	p = new Lnode;   
	p->next= NULL;   //do while中的do 
	while(cin>>p->data){
		r->next= p;   //尾指针连接p指针 
		r= p;   //后移一位 
		p = new Lnode;
		p->next= NULL;  //do while 中的do 
	}
}

//单链表的清空
void ClearList(LinkList &T){
	Lnode *p = T->next;  //从首元结点开始删除 ,先让p指向首元节点 
	Lnode *q;   //p是“先锋”,他去负责移位,q是“执行者”,负责删除东西 
	while(p){
		q = p;   //“先锋”告诉“执行者” 要删啥 
		p = p->next;   //“先锋”去寻找下一个目标 
		delete(q);   //“执行者”删除东西 
		
	}
	T->next = NULL;   //善后工作,使得此链表符合空链表的特征 
	cout<<"SUCCESS!!!"<<endl;
}

//单链表的销毁
void DestroyList(LinkList &T){   //销毁操作就是把清空操作的q指针换成头指针T(既然都要销毁了,不用白不用) 
	Lnode *p = T;                //而且单链表销毁操作连头节点都不留,这一点和清空操作做区分 
	while(T){
		p = T;
		T = T->next;
		delete(p);
	}
	cout<<"SUCCESS!!!"<<endl;	
} 

//求单链表长度
void ListLength(LinkList &T){   //创一个指针从受源节点往后数,数到一个i++ 
	Lnode *p = T->next;
	int i = 0;
	while(p){
		i++;
		p = p->next;
	}
	cout<<"单链表长度为:"<<i<<endl;
}

//按位置查找 
int GetElem(LinkList &T,int i,int &e){
	Lnode* p = T->next;    //创建一个指针指向首元节点 
	int j = 1;   //计数器 
	while(j<i){
		p=p->next;  //向后查找 
		j++;   //计数器加一 
	}
	e = p->data;   //保存查找的数据 
	cout<<e<<endl;
	return 0;
}

//按值查找,返回其序号 
int LocateList(LinkList T,int e){
	Lnode *p = T->next;
	int i= 1;
	while(p&&p->data!=e){
		p = p->next;
		i++;
	} 
	cout<<"值为:"<<e<<"的结点为第"<<i<<"个结点"<<endl; 
	return 0;
}

//单链表的插入
int InsertList(LinkList &T,int i,int &e){
	Lnode *p = T;   //先建立一个指针指向头节点,准备向后移动i-1次 
	for(int j=1;j<i;j++){   //p指针向后移动i-1次 (插入位置是1就移动0次,插入位置是2就移动1次) 
		p = p->next;
	}
	Lnode *q;     //创建q指针用来开辟一个新的结点 
	q = new Lnode;
	q->data = e;   //把e存入新结点 
	q->next = p->next;   //连接新节点的屁股 
	p->next = q;   //连接新节点的头 
	cout<<"单链表插入成功"<<endl; 
	return 1;
} 


//单链表的删除
int deleteLnode(LinkList &T,int i,int &e){
	Lnode *p = T;   //创建一个指针指向头节点 
	for(int j=1;j<i;j++){   //for循环作用:让p指向要删除节点的前一个结点 
		p = p->next;
	}
	e = p->next->data;   //p为要删除的节点的前一个,所以p的后一个结点的data就是目标内容 
	p->next = p->next->next;   //把链表连起来,不能因为删除了一个结点就使链表整个断开 
	cout<<"已删除"<<e<<endl;
	return 0; 
}