数据结构严蔚敏----单链表基本操作12个

编程语言:C
编译环境:Dev-C++
源代码:

//单链表的存储结构
//12个基本操作
//1.Status InitList(LinkList *L) 构造一个空的单链表L(默认带头结点)
//  产生头结点,并初始化给头指针,判断是否成功,若失败,exit(OVERFLOW);
//  头结点的指针域置为空,return OK;
//2.Status DestroyList(LinkList *L) 销毁单链表L,前提L存在
//  借助辅助指针LinkList p从头结点开始释放,每释放一次就刷新头结点,直到头结点为空,return OK;
//3.Status ClearList(LinkList L) 将L重置为空表,前提L存在(注意这里不是*L,L作为头指针没有改变) 
//  令LinkList p指向第一个结点(p=L->next),借助辅助指针LinkList q从第一个结点开始释放,每释放一次就刷新第一个结点,直到p为空
//  头结点的指针域置为空,return OK; 
//4.Status ListEmpty(LinkList L) 若L为空表,则返回TRUE,否则返回FALSE,前提L存在
//  若头结点的指针域,即L->next为空,返回TRUE,否则返回FALSE 
//5.int ListLength(LinkList L) 返回L中数据元素个数,前提L存在
//  令LinkList p指向第一个结点,int i=0,当p不为空时,i++,p=p->next,return i; 
//6.Status GetElem(LinkList L,int i,ElemType *e) 用e返回L中第i个数据元素的值,前提L存在
//  先判断i的值是否小于1,若是return ERROR; 
//  令LinkList p指向第一个结点,经过i-1个循坏后,令p指向第i个结点(若单链表的长度小于i,循环次数不会达到i-1,循环结束时p为空)
//  判断p是否为空,若是return ERROR;否则*e=p->data;return OK;
//7.int LocateElem(LinkList L,ElemType e) 若e在L中存在,返回它的位置,否则返回0,前提L存在
//  令LinkList p指向第一个结点,int i=1,不停地循环,直到p->data==e,return i,若循环结束时p为空,return 0;
//8.Status PriorElem(LinkList L,ElemType cur_e,ElemType *pre_e) 用pre_e返回L中cur_e的前驱元素,前提L存在 
//  很明显,要借助两个指针变量,与第7个基本操作类似,先找到cur_e的位置
//9.Status NextElem(LinkList L,ElemType cur_e,ElemType *next_e) 用next_e返回L中cur_e的后继元素,前提L存在
//  这个只需要一个指针变量p,与第7个基本操作类似,先找到cur_e的位置,最后*next_e=p->next->data;
//10.Status ListInsert(LinkList L,int i,ElemType e) 在L中第i个位置之前插入新的数据元素e,前提L存在 
//   先判断i的值是否合理 
//   这个只需要一个指针变量p,令p指向第i-1个结点,链表的插入比较简单,开辟新结点q即可 
//11.Status ListDelete(LinkList L,int i,ElemType *e) 删除L的第i个数据元素,并用e返回其值,前提L存在
//   先判断i的值是否合理
//   很明显,要借助两个指针变量,链表的删除比较简单
//12.Status ListTraverse(LinkList L) 单链表的遍历:依次访问表中每一个元素,前提L存在
//   令LinkList p=L->next,不停循环printf("%d ");p=p->next;直到p为空,最后printf("\n");
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
//函数结果状态代码
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define TRUE 1
#define FALSE 0

typedef int Status;
typedef int ElemType;
//单链表的存储结构
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;
//1.构造一个空的单链表L(默认带头结点)
Status InitList(LinkList *L)
{
	*L=(LinkList)malloc(sizeof(LNode));
	if(!*L) exit(OVERFLOW);
	(*L)->next=NULL;
	return OK;
}
//2.销毁单链表L,前提L存在
Status DestroyList(LinkList *L)
{
	LinkList p;
	while(*L)
	{
		p=(*L)->next;
		free(*L);
		*L=p;
	}
	return OK;
}
//3.将L重置为空表,前提L存在
Status ClearList(LinkList L)
{
	LinkList p=L->next;
	LinkList q;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL;
	return OK;
}
//4.探空
Status ListEmpty(LinkList L) 
{
	if(L->next==NULL)
	    return TRUE;
	else
	    return FALSE;
}
//5.返回L中数据元素个数,前提L存在
int ListLength(LinkList L)
{
	LinkList p=L->next;
	int i=0;
	while(p)
	{
		i++;
		p=p->next;
	}
	return i;
}
//6.用e返回L中第i个数据元素的值,前提L存在
Status GetElem(LinkList L,int i,ElemType *e)
{
	if(i<1) return ERROR;
	int j=1;
	LinkList p=L->next;
	while(j<i&&p)
	{
		p=p->next;	
		j++;
	}
	if(!p) return ERROR;
	else 
	{
		*e=p->data;
		return OK;
	}
}
//7.若e在L中存在,返回它的位置,否则返回0,前提L存在
Status LocateElem(LinkList L,ElemType e)
{
	LinkList p=L->next;
	int i=1;
	while(p)
	{
		if(p->data==e)
			return i;
		else
		{
			p=p->next;
			i++;
		}
	}
	return 0;
}
//8.用pre_e返回L中cur_e的前驱元素,前提L存在
Status PriorElem(LinkList L,ElemType cur_e,ElemType *pre_e)
{
	LinkList q=L->next;//第一个结点 
	if(!q)//若链表为空 
	    return ERROR; 
	LinkList p=q->next;//第二个结点
	while(p)
	{
		if(p->data==cur_e)
		{
			*pre_e=q->data;
			return OK;
		}
		else
		{
			q=p;
			p=p->next;
		}
	} 
    return ERROR; 
}
//9.用next_e返回L中cur_e的后继元素,前提L存在
Status NextElem(LinkList L,ElemType cur_e,ElemType *next_e)
{
	LinkList p=L->next;
	while(p)
	{
		if(p->data==cur_e&&p->next)
		{
			*next_e=p->next->data;
			return OK; 
		}
		else
		    p=p->next;
	}
	return ERROR;
}
//10.在L中第i个位置之前插入新的数据元素e,前提L存在
Status ListInsert(LinkList L,int i,ElemType e)
{
	if(i<1) return ERROR;
	int j=0;
	LinkList p=L;
	while(j<i-1&&p)
	{
		p=p->next;
		j++;
	}//令p指向第i-1个结点
	if(!p) return ERROR;
	LinkList q=(LinkList)malloc(sizeof(LNode));
	q->data=e;
	q->next=p->next;
	p->next=q;
	return OK;
}
//11.删除L的第i个数据元素,并用e返回其值,前提L存在
Status ListDelete(LinkList L,int i,ElemType *e)
{
	if(i<1) return ERROR;
	int j=1;
	LinkList p=L->next,q;
	while(j<i&&p)
	{
		q=p;
		p=p->next;
		j++;
	}
	if(!p) return ERROR;
	*e=p->data;
	q->next=p->next;
	free(p);
	return OK;
}
//12.单链表的遍历:依次访问表中每一个元素,前提L存在
Status ListTraverse(LinkList L)
{
	LinkList p=L->next;
	if(!p)
	    printf("链表为空!"); 
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
	return OK;
} 
int main()
{
	LinkList L;
	int j,j1;
	ElemType e=0,e1=0;
	printf("测试第一个基本操作(构造空链表)\n");
	InitList(&L);
	printf("此时链表中的元素为:");
	ListTraverse(L);
	printf("\n\n测试第十个基本操作(插入数据元素)\n");
	for(j=1;j<=5;j++)
	    ListInsert(L,1,j);
	printf("在表头依次插入1~5后,此时链表中的元素为:\n");
	ListTraverse(L);
	printf("第十二个基本操作测试成功!\n");
	for(j=6;j<=11;j++)
	    ListInsert(L,j,j);
	printf("在表尾依次插入6~11后,此时链表中的元素为:\n");
	ListTraverse(L);
	printf("\n\n测试第三、第四个基本操作:\n");
	printf("链表是否为空(1为空,0为不空):%d\n",ListEmpty(L));
	ClearList(L);
	printf("表清空后,链表是否为空(1为空,0为不空):%d\n",ListEmpty(L));
	printf("\n\n在表尾依次插入1~18。\n");
	for(j=1;j<=18;j++)
	    ListInsert(L,j,j);
	printf("此时链表中的元素为:");
	ListTraverse(L);
	printf("\n\n测试第五个基本操作(返回数据元素个数)\n");
	printf("表中数据元素的个数为%d\n",ListLength(L));
	printf("\n\n测试第六个基本操作(返回第十八个、第十九个数据元素的值)\n");
	GetElem(L,18,&e);
	GetElem(L,19,&e1);
	printf("第十八个数据元素为%d,第十九个数据元素为%d\n",e,e1);
	printf("\n\n测试第七个基本操作\n");
	j=LocateElem(L,18);
	j1=LocateElem(L,19);
	printf("18的位序为%d,19的位序为%d\n",j,j1);
	printf("\n\n测试第八个基本操作\n");
	e=0;
	e1=0;
	PriorElem(L,1,&e);
	PriorElem(L,18,&e1);
	printf("1的前驱为%d,18的前驱为%d\n",e,e1);
	printf("\n\n测试第九个基本操作\n");
	e=0;
	e1=0;
	NextElem(L,1,&e);
	NextElem(L,18,&e1);
	printf("1的后继为%d,18的后继为%d\n",e,e1);
	printf("\n\n测试第十一个基本操作\n");
	e=0;
	ListDelete(L,6,&e);
	printf("删除第六个数据元素:%d\n",e);
	printf("此时链表中的元素为:");
	ListTraverse(L);
	printf("\n\n测试第十二个操作\n");
	DestroyList(&L);
	printf("成功销毁链表!");
	return 0;
}

运行结果:

  • 14
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值