严蔚敏C语言版数据结构之单链表的十二个基本操作

PS:如果手机显示不完全可以用电脑查看

#include<stdio.h>
#include<stdlib.h>

#define ok 1
#define error 0

typedef int status;
typedef int elemtype;

typedef struct lnode
{
	elemtype data;
	struct lnode *next;
} lnode, *linklist;

status initlist_l(linklist &l)//初始化链表
{
	l = (linklist)malloc(sizeof(lnode));//申请一个头结点
	if (!l)
		return error;//申请失败
	l->next = NULL;//将表头置空
	return ok;

}

status createlist_l(linklist &l,int n)
//创建单链表头结点和n个元素结点
{
	int i;
	l = (linklist)malloc(sizeof(lnode));
	l->next = NULL;
	if (!l)
		return error;//头结点申请失败
	for (i = n; i >0; i--)//结点位置从1开始
	{
		linklist p = (linklist)malloc(sizeof(lnode));
		p->data = i * 2;
		p->next = l->next;
		l->next = p;
		
	}
	return ok;
}

status listinser_l(linklist &l, int i, elemtype e)//在单链表的第i个位置插入元素e
{
	linklist p = l;//p指向表头
	int j = 0;
	while (p&&j < i - 1)//使p到达i-1的位置
	{
		p = p->next;
		++j;
	}
	linklist s = (linklist)malloc(sizeof(lnode));//重新创建一个链表s
	s->data = e;
	s->next = p->next;//把p的链尾接入到s->next中
	p->next = s;//再把链头指向s
	return ok;//插入成功
}

status listdelete_l(linklist &l, int i, elemtype &e)//删除单链表的第i个元素,用e返回
{
	linklist p = l;
	int j = 0;
	while (p&&j<i-1)//使p达到i-1的位置
	{
		p = p->next;
		++j;
	}
	if (!p || i - 1 < j)
		return error;
	linklist s = p;//将s链入p的第一个节点
	e= s->next->data;//要删除的元素,用e返回
	s = p->next;//将s指到p->next,也就是第i个位置
	p->next = s->next;//等式于p->next=p->next->next,也就是跳过s的位置
	free(s);//删除s
	return ok;//删除成功
}
status getelem_l(linklist l, int i, elemtype &e)//获取单链表的第i个位置的元素,用e返回
{
	linklist p = l;
	int j = 0;
	while (p&&j<i)//使p达到i的位置
	{
		p = p->next;
		++j;
	}
	if (!p || j>i)
		return error;//输入的长度不合理
	e = p->data;
	return ok;
}

int locateelem_l(linklist l, elemtype e)//找出元素e在单链表中的位置
{
	linklist p = l->next;//使p指向l的第一个节点
	int i = 1;//所以i从1开始
	while (p&&p->data != e)//查找成功或者查找不到都要结束
	{
		p = p->next;
		++i;
	}
	if (!p)
		return error;
	return i;//返回元素e的位置
}

status printlist_l(linklist l)//遍历输出单链表中的所有元素
{
	linklist p = l->next;//p指向l的第一个节点
	while (p)
	{
		printf("%4d", p->data);
		p = p->next;
	}
	printf("\n");
	return ok;
}
status freelist_l(linklist &l)//销毁单链表
{
	linklist p = l;//p指向头节点
	while (p)
	{
		
		l = l->next;//l指向下一个节点
		free(p);//释放l的前一个节点
		p = l;//p对l进行追踪
	}
	return ok;
}

status clearlist_l(linklist &l)//置空单链表
{
	l->next=NULL;
	return ok;
}

void listlength_l(linklist l)//求单链表的长度
{
	int i = 0;//因为当p->next==NULL时还执行了一次++i,所以i从0开始
	linklist p = l->next;
	while (p!= NULL)
	{
		++i;
		p = p->next;
	}
	printf("此时单链表的长度为:%d\n",i);
}

status listempty_l(linklist l)//判断单链表是否为空
{
	if (l->next== NULL)
		return ok;
	else
		return error;
}

status priorelem_l(linklist l, elemtype cur_e, elemtype &pre_e)//求元素cur_e的前驱
{
	linklist p = l->next;//p指向l的第一个节点
	linklist q = l;//q指向l的表头,所以q为p的前一个节点
	if (p->data == cur_e)
		return error;//第一个节点无前驱
	while (p->data != cur_e&&p)//p找到cur_e元素时结束
	{
		p = p->next;
		q = q->next;
	}
	if (!p)
		return error;//链表中没有cur_e这个元素
	pre_e = q->data;
	return ok;
}

status nextelem_l(linklist l, elemtype cur_e, elemtype &next_e)//求元素cur_e的后继元素
{
	linklist p = l->next;
	while (p->data != cur_e&&p)
	{
		p = p->next;
	}
	if (!p)
		return error;
	next_e = p->next->data;//p的当前节点的下一个节点则为p的后继
	return ok;
}
int main()
{
	int i, length;
	linklist l;
	elemtype e,m;
	if (initlist_l(l) == ok)
		printf("链表初始化成功!\n");
	else
		printf("链表初始化失败!\n");
	createlist_l(l, 5);
	printf("链表的初始状态为:\n");
	printlist_l(l);
	printf("在链表的第二个位置插入99后的链表为:\n");
	listinser_l(l, 2, 99);
	printlist_l(l);
	listlength_l(l);
	printf("删除链表的三个位置后的链表为:\n");
	listdelete_l(l, 3, e);
	printlist_l(l);
	printf("被删除的元素是:%d\n", e);
	listlength_l(l);
	getelem_l(l, 3, e);
	printf("链表的第三个元素是:%d\n", e);
	priorelem_l(l, e, m);
	printf("%d的前驱是:%d\n",e, m);
	nextelem_l(l, e, m);
	printf("%d的后继是:%d\n", e, m);
	clearlist_l(l);
	if (listempty_l(l) == ok)
		printf("此时的链表已经为空!\n");
	else
		printf("此时的链表不空,置空失败!\n");
	printlist_l(l);
	system("pause");
	return 0;
}
```c
在这里插入代码片

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值