2.单链表知识+基操代码 |二、线性表

目录

2.1 知识点复习

2.2 代码+注释

2.3 纯代码


2.1 知识点复习

    线性表的值特性:数据元素必须 同类型、有限、有序
    重要术语:表长、空表、表头、表尾、前驱、后继、位序(1开始)、下标(0开始)
    基本操作:创建、销毁、增删改查(在结点前还是结点后?)、判断空表、长度、打印输出等等
    存储/物理结构:顺序存储、链式存储(单链表、双链表、循环链表、静态链表)

2.2 代码+注释

快速定位:

功能 声明/函数体 行 功能 声明/函数体 行
结构体定义 6/6 头插建表 23/120
判断是否空表 16/33 增(第x个结点前) 25/130
求表长 17/38 增(第x个结点后) 27/212
输出链表数据 18/47 增(值x的结点前) 26/171
查(第x个结点值) 19/58 增(值x的结点后) 28/237
查(值为x的结点) 20/75 删(第x个结点) 30/264
尾插建表 22/101 删(值为x的结点) 31/284

 代码:

        一些地方的合理性判断有略去,需要的可以自行添上。加注释的代码有点乱,后面有贴上无注释的版本的。水平有限,欢迎留言交流

#include<stdio.h>//null要用大写 NULL,不然会报错
#include<stdlib.h>//malloc的头文件 
#include<iostream>//c++头文件,是为了c++使用输入输出语句,可以用printf、scanf替代cout、cin 
using namespace std;//和c++ <iostream>配套的 

struct Link{ 
	int data;
	struct Link* next;
}*Lhead=NULL,*Lnode,*Lnext;
/*头结点Lhead不存数据,只是为了操作方便;空表判断:head->next==null?  
 头结点Lhead不存数据,只是为了操作方便;空表判断:head->next==null?
 Lnode:创建时,代表目前链表内存在的最新的结点
 Lnext:创建时,代表即将加入链表的结点(即下一个结点)
 struct {}结尾要用分号 ; 
 */
bool isvoid(Link *t);//判空 
int Getlength(Link *t);//表长 
void print(Link *t);//打印 
Link* Getdata_index(Link *t,int i);//查,第 i 个结点值 
void Getdata_value(Link *t,int i);//查,值为 i 的结点位序 

void init_tail(Link* &t,int x,int d);//尾插建表 
void init_head(Link* &t,int x,int d);//头插建表 

void add_before_index(Link* &t,Link* insert,int i);//增,第 i 个结点前插 
void add_before_value(Link* &t,Link* insert,int i);//增,值为 i 的结点前插 
void add_follow_index(Link* &t,Link* insert,int i);//增,第 i 个结点后插 
void add_follow_value(Link* &t,Link* insert,int i);//增,值为 i 的结点后插 

void deletenode_index(Link* &t,int i) ;//删,删第 i 个结点 
void deletenode_value(Link* &t,int value);//删,删值为 i 的结点 

bool isvoid(Link *t){//判断是否空表 ,true=void,false=not void 
	if(t==NULL)
		return true;
	return false;
} 
int Getlength(Link *t){
	if(isvoid(t)) return 0;//空表 
	int len=0;
	while(t!=NULL){
		len++;
		t=t->next;
	}
	return len;
} 
void print(Link *t){//从表头开始输出
	cout<<"当前链表内容:";//
	if(isvoid(t)){
		cout<<"空表"<<endl;return ; 	
	}
 	while(t!=NULL){
 		cout<<t->data<<"  ";
 		t=t->next;
 	}
 	cout<<endl;
}
Link* Getdata_index(Link *t,int i){//根据位序查找,get第 i 个结点的值
	int index=1;//位序是从1开始的,下标是从0开始的,这里用index代表位序 
	printf("	查找第%d个结点的值,结果是:",i); 
	if(isvoid(t)){
		cout<<"空表"<<endl;return NULL; 	
	}
	while(t!=NULL){//有查找的余地 
		if(index==i){
			cout<<t->data<<endl;
			return t;	//找到了就结束 
		}else{
			t=t->next;
			index++;
		}
	} 
	cout<<"超出链表范围"<<endl; return NULL; 	
} 
void Getdata_value(Link *t,int i){//根据结点值查找,get结点的值为 i 的结点位序 
	int index=1;//位序是从1开始的,下标是从0开始的,这里用index代表位序 
	int flag=0;	//是否有符合条件的结点存在 
	printf("	查找结点值为%d的结点位序是:",i); 
	if(isvoid(t)){
		cout<<"空表"<<endl;return ; 	
	}
	while(t!=NULL){//有查找的余地 
		if(t->data==i){
			cout<<index<<"  ";//不结束的原因是,可能有多个结点符合条件 
			flag=1; 
		}
		t=t->next;
		index++;
	} 
	if(flag==0)
	{cout<<"不存在"<<endl;}	
	else cout<<endl;
} 

/*用尾插法,顺序建表,输入data顺序和生成链表的数据顺序一样
函数两种写法:
一、使用指针返回值,main中引用的时候应该为 xx=init_tail(...);  
二、使用 & ,最后可以不返回
*/
//Link* init_tail(Link* t,int x,int d){//写法一 
void init_tail(Link* &t,int x,int d){//写法二 (链表,长度,值)如果自己输入值的话,可以去掉 d,下面加输入语句 
	while(x--){//
		Lnext=(Link *)malloc(sizeof(Link));
		Lnext->data=d;
		Lnext->next=NULL;//NULL一定要大写 
		
		if(Lhead==NULL)//创建了第一个结点 
			Lhead=Lnode=Lnext;//头结点和链表内的最新结点都是Lnext 
		else
			Lnode->next=Lnext;//让之前的最新结点next指针指向新建立的结点,二者链接 
		Lnode=Lnext;//之前的最新结点 更新 成新加入的结点 
		d++;
	} 
//	//辅助输出,检查创建结果 
//	cout<<"init:";
//	print(Lhead);//输出,查看创建结果: “1 2 3 4 5 6 7 8 9 10 ” 
	t=Lhead;//最后回到 t ,不要忘记了!!! 
//	return t;//写法一、记得把指针返回回去 
} 
void init_head(Link* &t,int x,int d){
	
	while(x--)	{
		Lnext=(Link *)malloc(sizeof(Link));
		Lnext->data=d;
		Lnext->next=t;
		t=Lnext;
		d++; 
	}
}
void add_before_index(Link* &t,Link* insert,int i) {/*在已有的第 i个结点前面,插入新结点,t是要进行操作的链表,insert是要加入的新结点*/
	
//	printf("1 %p\n",insert->next);//注释一、检查插入结点的next指针地址 
	Link* headtemp=(Link*)malloc(sizeof(Link));//Q2.1 
	headtemp=t; //Q2.1 
	/*Q2:为什么要再来一个headtemp?
   	  A2:因为这里用的是 &t,对它的改变是“永久”的,headtemp和 t指向同一地址,但是headtemp的挪动不影响 t的值,如果直接用t,头结点的地址会发生改变 
   	  而前面的void print(...)就不会有这个问题 
	验证:把 Q2.1换成注释状态,之后(运行注释二代码,再把本函数内的headtemp替换成 t),比较两种情况的运行结果 
	PS:能正确运行的是Q2.1*/

//	printf("1tou t=%p",t);//注释二、辅助检查,检查表头指针地址 
//	printf("1tou t=%p,headtemp=%p\n\n",t,headtemp);//Q2.1 
	printf("值%d插在第%d个结点前:\n",insert->data,i);
	cout<<"		旧:"; print(headtemp);
	i=i-1;//在第i个结点前面=在第i-1个结点后面,所以遍历到第 i-1个结点就可以操作了 
	int num=1;//
	int len=Getlength(headtemp);
	//接下来判断插入的位置是否合理 
	if(i>len||i<0||len==0){//超出表的范围 OR 空表 
		cout<<"		新:add error"<<endl;
		return;
	}else if(i==0){//插在原本的表头前面 
		insert->next=t;
//		printf("2 %p",insert->next);//注释一、检查插入结点的next指针地址 
		t=insert;
	}else{//插在表中间 
			while(headtemp!=NULL){// 
				if(num==i){
					insert->next=headtemp->next;
					headtemp->next=insert; 
				}
				headtemp=headtemp->next;
				num++; 
		}
	}
	//输出检查
	cout<<"		新:"; print(t);
//	printf("2tou t=%p\n\n",t);//注释二、辅助检查,检查表头指针地址 
//	printf("2tou t=%p,headtemp=%p\n\n",t,headtemp);//Q2.1辅助检查,检查表头指针地址  
}
void add_before_value(Link* &t,Link* insert,int i) {/*在已有的第index个结点前面,插入新结点,t是要进行操作的链表,insert是要加入的新结点*/
	//设定:有data==i 就插,可以插多个,只考虑插值,不考虑指针地址 
	printf("在值%d前插%d的结果是:",i,insert->data);
	cout<<endl<<"		旧:";	print(t);
	if(isvoid(t)){
		cout<<"空表 error"<<endl;return; 	
	}
	Link* headtemp=(Link *)malloc(sizeof(Link));//上一个结点 
	headtemp=t;
	
	Link* copy= (Link *)malloc(sizeof(Link));
	copy->data=insert->data;//复制值 
	copy->next=NULL;
	
	int flag=0; //是否存在符合条件的结点 
	if(t->data==i){//先把表头解决了
		flag=1;
		copy->next=t;
		t=copy;
		headtemp=headtemp->next; //往下挪一个结点,否则会出现第一个结点前重复插入 
//		cout<<"first  ";//辅助输出检查 
//		print(t);
	}
	
	while(headtemp->next!=NULL){//NULL 
		if(headtemp->next->data==i){
				flag=1;
				Link* copy2= (Link *)malloc(sizeof(Link)); //每用一个都要重新malloc = 在硬件上申请一个地址给指针存放数据用,不申请就没地方放 
				copy2->data=insert->data;	//复制值 
				
				copy2->next=headtemp->next; //这两句顺序不能颠倒,若先执行headtemp->next=copy,指向其原后继的指针就不存在,
				headtemp->next=copy2;// 然后copy->next=headtemp 相当于的copy->next=copy,显然错误 
				
				headtemp=copy2->next;//画图感受一下,这里的结点关系 
				
		}else headtemp=headtemp->next;//简单的往下挪 
	}
	cout<<"		新:";	print(t);
	if(flag==0)
		cout<<"不存在"<<endl; 
}
void add_follow_index(Link* &t,Link* insert,int i) {// 

	Link* headtemp=(Link*)malloc(sizeof(Link));
	headtemp=t; 
	int num=1,len=Getlength(t);
	
	printf("值%d插在第%d个结点后:\n",insert->data,i);
	cout<<"		旧:"; print(headtemp);
	if(i>len||i<0||len==0){//超出表的范围 OR 空表 
		cout<<"		新:add error"<<endl;
		return;
	}
	while(headtemp!=NULL){
		if(num==i&&headtemp->next!=NULL){//不在表尾 
			insert->next=headtemp->next;
			headtemp->next=insert; 
		}else if(num==i&&headtemp->next==NULL){//在表尾 
			headtemp->next=insert;
			break;
		} 
		headtemp=headtemp->next;
		num++; 
	}
	cout<<"		新:"; print(t);
}
void add_follow_value(Link* &t,Link* insert,int i) {
		//设定:有data==i 就插,可以插多个,只考虑插值,不考虑指针地址 
	printf("在值%d后插%d的结果是:",i,insert->data);
	cout<<endl<<"		旧:";	print(t);
	if(isvoid(t)){
		cout<<"空表 error"<<endl;return; 	
	}
	Link* headtemp=(Link *)malloc(sizeof(Link));//当前结点 
	headtemp=t;
	
	int flag=0; //是否存在符合条件的结点 
	
	while(headtemp!=NULL){//NULL 
		if(headtemp->data==i){
				flag=1;
				Link* copy2= (Link *)malloc(sizeof(Link)); //每用一个都要重新malloc = 在硬件上申请一个地址给指针存放数据用,不申请就没地方放 
				copy2->data=insert->data;	//复制值 
				
				copy2->next=headtemp->next; //这两句顺序不能颠倒,若先执行headtemp->next=copy,指向其原后继的指针就不存在,
				headtemp->next=copy2;// 然后copy->next=headtemp 相当于的copy->next=copy,显然错误 
		}
		 headtemp=headtemp->next;//简单的往下挪 
	}
	cout<<"		新:";	print(t);
	if(flag==0)
		cout<<"不存在"<<endl; 
}
void deletenode_index(Link* &t,int i) {//
	cout<<"删除第"<<i<<"个结点:"<<endl; 
	cout<<"		旧:";print(t);
	if(i==1){
		//新建一个结点=头结点 
		t=t->next;
		//释放上面建的结点,这个过程略 
	}
	else{
		cout<<"		";
		Link* front_node=Getdata_index(t,i-1);
		cout<<"		";
		Link* node=Getdata_index(t,i);
		
		front_node->next=front_node->next->next;
		free(node);
	}
	
	cout<<"		新:";print(t); 
}
void deletenode_value(Link* &t,int value) {// 
//删除第一个data等于value的结点
	//把下面删除多个的,修改一下,遇到第一个符合条件的直接结束 
//删除所有data等于value的结点 
	cout<<"删除值="<<value<<"的结点:"<<endl; 
	cout<<"		旧:";print(t);
	//如果第一个结点data=value 
	if(t->data==value){
		//释放过程略 
		t=t->next;
	}
	
	Link* temp=(Link*)malloc(sizeof(Link));
	temp=t;
	
	while(temp->next->next!=NULL)//头部和中间 
	{
		if(temp->next->data==value)
		{
			Link* node=(Link*)malloc(sizeof(Link));
			
			node=temp->next;
			temp->next=temp->next->next;
			temp=temp->next->next;
			free(node);
		}
		else temp=temp->next;
	}
	if(temp->next->data==value)
		temp->next=NULL;//释放过程略 
	cout<<"		新:";print(t);
}
	
int main(){
	int x=10;//限定结点个数,方便用while创建 
	int d=1;//用顺序数填充数据域,通过输出便于观察头插尾插效果 
	
	//尾插建表 
	Link* tailLink=(Link*)malloc(sizeof(Link));//tail:尾部的意思 
//	tailLink=init_tail(tailLink,x,d);//尾插,写法一 
	init_tail(tailLink,x,d);//尾插,写法二 
		print(tailLink);//输出,查看创建结果 “1 2 3 4 5 6 7 8 9 10 ” 
	
	//头插建表 
	Link* headLink=(Link*)malloc(sizeof(Link));
	headLink=NULL;
	init_head(headLink,x,d);
		print(headLink);
	
	//查找,根据位序OR元素值查找 
	Getdata_index(tailLink,2);
	Getdata_index(tailLink,11);
	Getdata_value(tailLink,5);
	Getdata_value(tailLink,12); 

	//
	int addop[]={1,5,19,-1,Getlength(tailLink)};
	//根据位序扦插, 在第 i 个结点前插入某个结点 
	for(int i=0;i<sizeof(addop)/sizeof(int)-1;i++){//addbefore 
	/*Q1:为什么使用循环?运行注释一的代码,看它们的输出,
	发现 指针addtemp在运行过程中会被修改,所以每次操作需要重新malloc */
		Link* addtemp=(Link*)malloc(sizeof(Link));
		addtemp->data=99;
		addtemp->next=NULL;
		add_before_index(tailLink,addtemp,addop[i]);
		cout<<"		表长:"<<Getlength(tailLink)<<endl;
	}
	//根据位序后插,在第 i 个结点后插入某个结点 
	for(int i=0;i<sizeof(addop)/sizeof(int);i++){//addfollow 
		Link* addtemp=(Link*)malloc(sizeof(Link));
		addtemp->data=100;
		addtemp->next=NULL;
		add_follow_index(tailLink,addtemp,addop[i]);
		cout<<"		表长:"<<Getlength(tailLink)<<endl;
	}
	//前插,在拥有某个特定元素值的结点后面插入某个结点 
	Link* addtemp=(Link*)malloc(sizeof(Link));
	addtemp->data=101;
	addtemp->next=NULL;
	add_before_value(tailLink,addtemp,99);
	//后插,在拥有某个特定元素值的结点后面插入某个结点 
	Link* addtemp2=(Link*)malloc(sizeof(Link));
	addtemp2->data=200;
	addtemp2->next=NULL;
	add_follow_value(tailLink,addtemp2,101);
	
	
	//删除,根据结点位序删除,删除第 i个结点 
	deletenode_index(tailLink,1);
	deletenode_index(tailLink,5);
	deletenode_index(tailLink,Getlength(tailLink));
	//删除,根据结点值删除,删除第 i个结点 
	deletenode_value(tailLink,Getdata_index(tailLink,1)->data);
	deletenode_value(tailLink,Getdata_index(tailLink,5)->data);
	deletenode_value(tailLink,Getdata_index(tailLink,Getlength(tailLink))->data);//因为表长一直在变化,表尾的话直接调用函数求
	
	return 0;
}

2.3 纯代码

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

struct Link{ 
	int data;
	struct Link* next;
}*Lhead=NULL,*Lnode,*Lnext;

bool isvoid(Link *t);//判空 
int Getlength(Link *t);//表长 
void print(Link *t);//打印 
Link* Getdata_index(Link *t,int i);//查,第 i 个结点值 
void Getdata_value(Link *t,int i);//查,值为 i 的结点位序 

void init_tail(Link* &t,int x,int d);//尾插建表 
void init_head(Link* &t,int x,int d);//头插建表 

void add_before_index(Link* &t,Link* insert,int i);//增,第 i 个结点前插 
void add_before_value(Link* &t,Link* insert,int i);//增,值为 i 的结点前插 
void add_follow_index(Link* &t,Link* insert,int i);//增,第 i 个结点后插 
void add_follow_value(Link* &t,Link* insert,int i);//增,值为 i 的结点后插 

void deletenode_index(Link* &t,int i) ;//删,删第 i 个结点 
void deletenode_value(Link* &t,int value);//删,删值为 i 的结点 

bool isvoid(Link *t){
	if(t==NULL)
		return true;
	return false;
} 
int Getlength(Link *t){
	if(isvoid(t)) return 0;
	int len=0;
	while(t!=NULL){
		len++;
		t=t->next;
	}
	return len;
} 
void print(Link *t){
	cout<<"当前链表内容:";
	if(isvoid(t)){
		cout<<"空表"<<endl;return ; 	
	}
 	while(t!=NULL){
 		cout<<t->data<<"  ";
 		t=t->next;
 	}
 	cout<<endl;
}
Link* Getdata_index(Link *t,int i){
	int index=1;
	printf("	查找第%d个结点的值,结果是:",i); 
	if(isvoid(t)){
		cout<<"空表"<<endl;return NULL; 	
	}
	while(t!=NULL){ 
		if(index==i){
			cout<<t->data<<endl;
			return t;	
		}else{
			t=t->next;
			index++;
		}
	} 
	cout<<"超出链表范围"<<endl; return NULL; 	
} 
void Getdata_value(Link *t,int i){ 
	int index=1;
	int flag=0;	
	printf("	查找结点值为%d的结点位序是:",i); 
	if(isvoid(t)){
		cout<<"空表"<<endl;return ; 	
	}
	while(t!=NULL){ 
		if(t->data==i){
			cout<<index<<"  ";
			flag=1; 
		}
		t=t->next;
		index++;
	} 
	if(flag==0)
	{cout<<"不存在"<<endl;}	
	else cout<<endl;
} 


void init_tail(Link* &t,int x,int d){
	while(x--){
		Lnext=(Link *)malloc(sizeof(Link));
		Lnext->data=d;
		Lnext->next=NULL;
		
		if(Lhead==NULL)
			Lhead=Lnode=Lnext;
		else
			Lnode->next=Lnext; 
		Lnode=Lnext;
		d++;
	} 
	t=Lhead;
} 
void init_head(Link* &t,int x,int d){
	
	while(x--)	{
		Lnext=(Link *)malloc(sizeof(Link));
		Lnext->data=d;
		Lnext->next=t;
		t=Lnext;
		d++; 
	}
}
void add_before_index(Link* &t,Link* insert,int i) {
	Link* headtemp=(Link*)malloc(sizeof(Link));
	headtemp=t; 

	printf("值%d插在第%d个结点前:\n",insert->data,i);
	cout<<"		旧:"; print(headtemp);
	i=i-1;
	int num=1;
	int len=Getlength(headtemp);
	
	if(i>len||i<0||len==0){
		cout<<"		新:add error"<<endl;
		return;
	}else if(i==0){ 
		insert->next=t;
		t=insert;
	}else
			while(headtemp!=NULL){
				if(num==i){
					insert->next=headtemp->next;
					headtemp->next=insert; 
				}
				headtemp=headtemp->next;
				num++; 
		}
	}
	cout<<"		新:"; print(t);
}
void add_before_value(Link* &t,Link* insert,int i) {
	printf("在值%d前插%d的结果是:",i,insert->data);
	cout<<endl<<"		旧:";	print(t);
	if(isvoid(t)){
		cout<<"空表 error"<<endl;return; 	
	}
	Link* headtemp=(Link *)malloc(sizeof(Link));
	headtemp=t;
	
	Link* copy= (Link *)malloc(sizeof(Link));
	copy->data=insert->data;
	copy->next=NULL;
	
	int flag=0; 
	if(t->data==i){
		flag=1;
		copy->next=t;
		t=copy;
		headtemp=headtemp->next; 
	}
	
	while(headtemp->next!=NULL){
		if(headtemp->next->data==i){
				flag=1;
				Link* copy2= (Link *)malloc(sizeof(Link));
				copy2->data=insert->data;
				
				copy2->next=headtemp->next; 
				headtemp->next=copy2; 
				
				headtemp=copy2->next;
				
		}else headtemp=headtemp->next; 
	}
	cout<<"		新:";	print(t);
	if(flag==0)
		cout<<"不存在"<<endl; 
}
void add_follow_index(Link* &t,Link* insert,int i) {// 

	Link* headtemp=(Link*)malloc(sizeof(Link));
	headtemp=t; 
	int num=1,len=Getlength(t);
	
	printf("值%d插在第%d个结点后:\n",insert->data,i);
	cout<<"		旧:"; print(headtemp);
	if(i>len||i<0||len==0){
		cout<<"		新:add error"<<endl;
		return;
	}
	while(headtemp!=NULL){
		if(num==i&&headtemp->next!=NULL){
			insert->next=headtemp->next;
			headtemp->next=insert; 
		}else if(num==i&&headtemp->next==NULL){ 
			headtemp->next=insert;
			break;
		} 
		headtemp=headtemp->next;
		num++; 
	}
	cout<<"		新:"; print(t);
}
void add_follow_value(Link* &t,Link* insert,int i) {
	printf("在值%d后插%d的结果是:",i,insert->data);
	cout<<endl<<"		旧:";	print(t);
	if(isvoid(t)){
		cout<<"空表 error"<<endl;return; 	
	}
	Link* headtemp=(Link *)malloc(sizeof(Link));
	headtemp=t;
	
	int flag=0; 
	
	while(headtemp!=NULL){
		if(headtemp->data==i){
				flag=1;
				Link* copy2= (Link *)malloc(sizeof(Link)); 
				copy2->data=insert->data;
				
				copy2->next=headtemp->next; 
				headtemp->next=copy2;
		}
		 headtemp=headtemp->next;
	}
	cout<<"		新:";	print(t);
	if(flag==0)
		cout<<"不存在"<<endl; 
}
void deletenode_index(Link* &t,int i) {
	cout<<"删除第"<<i<<"个结点:"<<endl;
	cout<<"		旧:";print(t);
	if(i==1){
		t=t->next;
	}
	else{
		cout<<"		";
		Link* front_node=Getdata_index(t,i-1);
		cout<<"		";
		Link* node=Getdata_index(t,i);
		
		front_node->next=front_node->next->next;
		free(node);
	}
	
	cout<<"		新:";print(t); 
}
void deletenode_value(Link* &t,int value) {
	cout<<"删除值="<<value<<"的结点:"<<endl; 
	cout<<"		旧:";print(t);
	if(t->data==value){
		t=t->next;
	}
	
	Link* temp=(Link*)malloc(sizeof(Link));
	temp=t;
	
	while(temp->next->next!=NULL)
	{
		if(temp->next->data==value)
		{
			Link* node=(Link*)malloc(sizeof(Link));
			
			node=temp->next;
			temp->next=temp->next->next;
			temp=temp->next->next;
			free(node);
		}
		else temp=temp->next;
	}
	if(temp->next->data==value)
		temp->next=NULL;
	cout<<"		新:";print(t);
}
	
int main(){
	int x=10;
	int d=1;
	
	Link* tailLink=(Link*)malloc(sizeof(Link));
	init_tail(tailLink,x,d);
		print(tailLink);
	
	//头插建表 
	Link* headLink=(Link*)malloc(sizeof(Link));
	headLink=NULL;
	init_head(headLink,x,d);
		print(headLink);
	
	//查找,根据位序OR元素值查找 
	Getdata_index(tailLink,2);
	Getdata_index(tailLink,11);
	Getdata_value(tailLink,5);
	Getdata_value(tailLink,12); 

	//
	int addop[]={1,5,19,-1,Getlength(tailLink)};
	//根据位序扦插, 在第 i 个结点前插入某个结点 
	for(int i=0;i<sizeof(addop)/sizeof(int)-1;i++){//addbefore 
	/*Q1:为什么使用循环?运行注释一的代码,看它们的输出,
	发现 指针addtemp在运行过程中会被修改,所以每次操作需要重新malloc */
		Link* addtemp=(Link*)malloc(sizeof(Link));
		addtemp->data=99;
		addtemp->next=NULL;
		add_before_index(tailLink,addtemp,addop[i]);
		cout<<"		表长:"<<Getlength(tailLink)<<endl;
	}
	//根据位序后插,在第 i 个结点后插入某个结点 
	for(int i=0;i<sizeof(addop)/sizeof(int);i++){//addfollow 
		Link* addtemp=(Link*)malloc(sizeof(Link));
		addtemp->data=100;
		addtemp->next=NULL;
		add_follow_index(tailLink,addtemp,addop[i]);
		cout<<"		表长:"<<Getlength(tailLink)<<endl;
	}
	//前插,在拥有某个特定元素值的结点后面插入某个结点 
	Link* addtemp=(Link*)malloc(sizeof(Link));
	addtemp->data=101;
	addtemp->next=NULL;
	add_before_value(tailLink,addtemp,99);
	//后插,在拥有某个特定元素值的结点后面插入某个结点 
	Link* addtemp2=(Link*)malloc(sizeof(Link));
	addtemp2->data=200;
	addtemp2->next=NULL;
	add_follow_value(tailLink,addtemp2,101);
	
	
	 
	deletenode_index(tailLink,1);
	deletenode_index(tailLink,5);
	deletenode_index(tailLink,Getlength(tailLink));
	
	deletenode_value(tailLink,Getdata_index(tailLink,1)->data);
	deletenode_value(tailLink,Getdata_index(tailLink,5)->data);
	deletenode_value(tailLink,Getdata_index(tailLink,Getlength(tailLink))->data);
	 
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45788060/article/details/126404756