链表的实现

#include <bits/stdc++.h>
#define OK 1
#define ERROR 0
using namespace std;
typedef int ElemType;
typedef int Status;
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}Lnode,*LinkList;
//初始化 
Status InitList(LinkList &L){
	L=(LinkList)malloc(sizeof(LNode));
	if(!L){
	exit(OVERFLOW);}
	L->next=NULL;
	return OK;
}
/*单链表的读取 
读取链表的第i个位置的元素,由e返回其值 
1. 声明一个结点 p 指向链表第一个结点,初始化 j 从 1 开始;
2. 当 j<i 时,就遍历链裴,让 p 的指针向后移动,不断指向下一结点, j 累加 1;
3. 若到链表末尾 p 为空,则说明第 i 个元素不存在;
4. 否则查找成功,返回结点 p 的数据。
*/ 
Status GetElem(LinkList L,int i,ElemType &e){
	LinkList p=L->next;//p指向首元结点
	int j=1;//j用于计数
	while(j<i&&p){ 
		p=p->next;
		j++;
	} 
	if(!p||j>i)
		return ERROR;//健壮性 
	e=p->data;
	return OK;
} 
/*插入算法:
L的第i个位置之前插入元素e 
1. 声明一结点 p 指向链表头结点,初始化 j 从 0 开始; 
2. 当 j<i-1 时,就遍历链表,让 p 的指针向后移动,不断指向下一结点, j 累加 1;
3. 若到链表末尾 p为空,则说明第 i 元素不存在;
4. 否则查找成功,在系统中生成一个空结点 s;
5. 将数据元素 e 赋值给 s->data ;
6. 单链表的插入标准语旬 s->next=p->next;p->next=s; 
7. 返回成功。
 */
Status ListInsert(LinkList &L,int i,ElemType e){
	LinkList p=L,s;
	int j=0;
	while(j<i-1&&p){
		j++;
		p=p->next;
	}
	if(j>i-1||!p){
		return ERROR;
	}
	s=(LinkList)malloc(sizeof(LNode));//建立一个新节点 
	s->data=e;//赋值 
//插入过程 
	s->next=p->next;
	p->next=s; 
	return OK;
}
/*删除算法
删除L的第i个元素,并由e返回其值 
1. 声明一结点 p 指向链表第一个结点,初始化j从0开始
2. 当 j<i-1同时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1
3. 若到链表末尾 p为空,则说明第i个元素不存在;
4. 否则查找成功,将欲删除的结点 p->next 赋值给 q;
S. 单链表的删除标准语句 p->next=q->next;
6. 将 q 结点中的数据赋值给 e, 作为返回;
7. 释放 q 结点;
8. 返回成功。*/
Status ListDelete(LinkList &L,int i,ElemType e){
	LinkList p=L;
	int j=0;
	while(j<i-1&&p->next){
		p=p->next;
		j++; 
	}
	if(j>i-1||(!p->next)){
		return ERROR;
	} 
	LinkList q;
	q=p->next;p->next=q->next;//删除结点 
	e=q->data;
	free(q);//释放结点空间 
	return OK;
}
/*按值查找
按值查找是在链表中,查找是否有结点值等于给定值key的结点,
若有的话,则返回首次找到的其值为key的结点的存储位置;
否则返回NULL。*/
Status LinkSearch(LinkList L,ElemType key,LNode *e){
	LinkList p=L;
	while(p->next&&p->next->data!=key){
		p=p->next;
	}
	if(!p->next)return ERROR;
	e=p->next;
	return OK;
} 
//前驱
Status LinkPiror(LinkList L,ElemType cur_e,ElemType &e){
	LinkList p=L->next;
	while(p->next){//p有后继 
		if(p->next->data==cur_e){//p的后继 
			e=p->data; 
			return OK;
		}
		p=p->next;
	}
	return ERROR;
}
//后继 
Status LinkNext(LinkList L,ElemType cur_e,ElemType &e){
	LinkList p=L->next;
	while(p->next){
		if(p->data==cur_e){
			e=p->next->data;
			return OK;
		}
		p=p->next;
	}	
	return ERROR;
}
/*销毁
1. 声明一个节点q
2. 让q等于L的下一个地址
3. 释放L,循环,直到表为空*/
void DestroyList(LinkList &L){
	LinkList q;
	while(L){
		q=L->next;
		free(L);
		L=q;
	}
}
/*清空
让头结点指针域为空*/
void ClearList(LinkList L){
	LinkList p=L->next;
	L->next=NULL;
	DestroyList(p);
}
//判空
void ListEmpty(LinkList L){
	int k;
	if(L->next==NULL)k=1;
	else k=0;
	if(k==1)
		printf("表为空\n") ;
	else 
		printf("表不为空\n");
} 
//求长(求元素个数)
int ListLength(LinkList L){
	int i=0;
	LinkList p=L->next;
	while(p){
		i++;
		p=p->next;
	}
	return i;
}
/*创建链表(头插法)
1. 声明一结点 p 和计数器变量 i
2. 初始化一空链表 L
3. 让 L 的头结点的指针指向 NULL,即建立一个带头结点的单链表
4. 循环:
	1生成一新结点赋值给 p;
	2将待插入的数字赋值给p的数据域 p->data;
	3将p插入到头结点与前一新结点之间。*/
void CreateListHead(LinkList &L,int n){
	//建立带头结点的链表L,逆位序输入n个元素值
	LinkList p;
	int i;
	InitList(L);
	for(i=0;i<n;i++){
		p=(LinkList)malloc(sizeof(LNode));//建立新节点 
		cin>>p->data;
		p->next=L->next;L->next=p;//插表头 
	} 
}
//创建链表(尾插法)
void CreateListTail(LinkList &L,int n){
	//建立带头结点的链表L,逆位序输入n个元素值
	LinkList p,r;
	int i;
	InitList(L);
	r=L;
	for(i=0;i<n;i++){
		p=(LinkList)malloc(sizeof(LNode));//建立新节点 
		cin>>p->data;
		r->next=p;//将表尾终端节点的指针指向新结点
		r=r->next;// 将当前的新节点定义为农表位终端节点
	} 
	p->next=NULL;//表示当前列表结束 
}
//遍历 
void show(LinkList L){
    LinkList p=L->next;
    while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
    }
    cout<<endl;
}
int main()
{
	LinkList L;
	ElemType e,e0;
	int i,j,k;
	InitList (L);//初始化
	cout<<"请输入待插入链表的5个数"<<endl; 
	CreateListHead(L,5);//头插法
	show(L); 
	ListEmpty(L);//判空
	printf("%d\n",ListLength(L));//求长度 
	ClearList(L);//清空 
	ListEmpty(L);//判空
	printf("%d\n",ListLength(L));//求长度 
	DestroyList(L);
	cout<<"请输入待插入链表的5个数"<<endl; 
	CreateListTail(L,5);//尾插法
	show(L);
	ListInsert(L,2,9);
	show(L);
	ClearList(L);//清空 
	for(j=1;j<=10;j++){
		ListInsert(L,1,j);//表尾插入 
	}
	show(L);
	//前驱,测试头两个元素
	for(j=1;j<=2;j++){
	 	GetElem(L,j,e0);
	 	i=LinkPiror(L,e0,e);
	 	if(i==ERROR)printf("元素%d无前驱\n",e0);
	 	else printf("元素%d的前驱为%d\n",e0,e);
	 }
	 //后继,测试后两个元素
	for(j=ListLength(L)-1;j<=ListLength(L);j++){
	 	GetElem(L,j,e0);
	 	i=LinkNext(L,e0,e);
	 	if(i==ERROR)printf("元素%d无后继\n",e0);
	 	else printf("元素%d的后继为%d\n",e0,e);
	 }
	//删除 
	i=ListDelete(L,5,e);
	if(i==ERROR)printf("删除第5个元素失败\n");
	else printf("删除第5个元素成功,其值为%d\n",e);
	i=ListDelete(L,12,e);
	if(i==ERROR)printf("删除第12个元素失败\n");
	else printf("删除第12个元素成功,其值为%d\n",e);
	DestroyList(L);//销毁L
	printf("销毁L后,L=%u\n",L); 
	return 0;
}

结果:

请输入待插入链表的5个数
1 2 3 4 5
5 4 3 2 1
表不为空
5
表为空
0
请输入待插入链表的5个数
5 4 3 2 1
5 4 3 2 1
5 9 4 3 2 1
10 9 8 7 6 5 4 3 2 1
元素10无前驱
元素9的前驱为10
元素2的后继为1
元素1无后继
删除第5个元素成功,其值为1
删除第12个元素失败
销毁L后,L=0
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值