C语言 数据结构 链表及其相关操作

1、链表:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,查找一个节点或者访问特定编号的节点则需要O(n)的时间

2、链表的声名与定义:

typedef struct node
{
	int nval;			//数据域
	struct node *pnext; //指针域
}list;

3、链表的创建:

list *createnode()
{
	list *phead = NULL;
	list *pend = NULL;
	list *ptmp = NULL;
	int cnt ;
	int n;
	scanf("%d",&cnt);
	while(cnt>0)
	{
		scanf("%d",&n);
		ptmp = (list *)malloc(sizeof(list));
		ptmp->nval = n;
		ptmp->pnext = NULL;
		if(phead == NULL)
		{
			phead = ptmp;
		}
		else
		{
			pend->pnext = ptmp;
		}
		pend = ptmp;
		cnt--;
	}
	return phead;
}

4、链表的打印:链表的输出可以是非递归的,也可以是递归的。

void outputnode(list *pnode)        //非递归打印链表
{
	while(pnode != NULL)
	{
		printf("%d ",pnode->nval);
		pnode = pnode->pnext;
	}
}

void diguioutputnode(list *pnode)    //递归打印链表
{
	if(pnode != NULL)    //如果该节点不是空,那么打印下一个
	{
		printf("%d ",pnode->nval);
		diguioutputnode(pnode->pnext);
	}
}

5.链表的逆序输出问题:我给出三种方法:第一种是将链表输入到数组中,再逆序输出;第二种方法是递归逆序打印链表想法类似于顺序递归打印;第三种方法是直接将原链表倒置。

void reverse_output(list *pnode)  //方法一:输入数组,逆序打印数组
{
	if(pnode==NULL) return ;
	int len = 0;
	int i = 0;
	list *pmark = pnode;
	while(pmark!=NULL)
	{
		len++;
		pmark = pmark->pnext;
	}
	int *p = (int *)malloc(sizeof(int)*len);
	while(pnode != NULL)
	{
		p[i] = pnode->nval;
		pnode = pnode->pnext;
		i++;
	}
	for(i=len-1;i>=0;i--)
	{
		printf("%d ",p[i]);
	}
	free(p);
	p = NULL;
}

list *reverse_list(list *phead)   //方法二:将链表倒置
{
	list *p1 = NULL;
	list *p2 = phead;
	list *p3 = phead->pnext;
	while(p3!=NULL)
	{
		p2->pnext = p1;
		p1 = p2;
		p2 = p3;
		p3 = p3->pnext;
	}
	p2->pnext = p1;
	return p2;
}

void digui_reverseoutputlist(list *phead)    //方法三:递归逆序链表
{
	if(phead == NULL)  //节点为空不打印
	{
		return ;
	}
	else	//节点不为空打印下一个;最后打印当前节点。
	{
		digui_reverseoutputlist(phead->pnext);
		printf("%d ",phead->nval);
	}
}

对于方法二的实现解释:

新建三个指针p2指向链表的头节点,p3指向链表的头节点的下一个节点(即phead->pnext),p1初值为空,将三个指针作为链表的三个节点顺着链表移动,当中将每一个节点的指向下一个节点指针(即p2->pnext)赋值为前一个节点(即p1)上。最后,要有一个p3作为边界条件,断开后让原链表的尾节点(p2)作为新链表的头,并且连接上新的链表,返回p2即可。

程序截图:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值