数据结构 单链表的其他操作

例题一:逆置单链表

void InvertLinkedList(LinkList &L)

本题的思路是创建链表之后,定义两个指针s,p p指针指向L,代替L的头指针功能,s指向每一个需要移动的结点。移动的顺序就是先让原来的头指针L=NULL, 然后将原链表的第一个结点删除,转接到新链表的L后面。往后原链表的每一个“头结点”都删除转接到L后面,形成逆置。

#include<stdio.h>

typedef struct LNode {
	int data;
	struct LNode *next;
}LNode, *LinkList;

void CreateList_L(LinkList &L, int a[], int n)
{
	int i;
	LNode *s;
	L = NULL;     //创建链表时一定不要忘记此处要让L=NULL!!!
	for (i = n - 1; i >= 0; i--)
	{
		s = new LNode;
		s->data = a[i];
		s->next = L;    //逆序创建时第一个结点是整个链表的尾节点,此时第一次是给其next指针赋值为NULL,第二次开始才是指向L所指结点
		L = s;
	}
}

void InvertLinkedList(LinkList &L)
{
	//逆置L所指的链表
	LNode *p, *s;
	p = L;
	L = NULL;
	while (p)
	{
		s = p;  //用s来指向每一个要移动的结点
		p = p->next;
		s->next = L;  //第一次时L=NULL,意为对s->next赋空值,后面的循环才是将s->next指向L;
		L = s;   //将s插入到逆置表的表头
	}
}

void main()
{
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	LNode *p;
	LinkList L;
	CreateList_L(L, a, 10);
	printf("逆置前的链表为:");
	for (p = L; p != NULL; p = p->next)
		printf("%d ", p->data);
	printf("\n");
	InvertLinkedList(L);
	printf("逆置后的链表为:");
	for (p = L; p != NULL; p = p->next)
		printf("%d ", p->data);
}

例题二:两个链表A,B 将B中含有而A中不含有的元素全部插入到A表中去

void union_L(LinkList &A, LinkList &B)

本题思路:首先判断A表是否为空,若不为空,则定义三个指针s , p , pre; s指针指向B的头结点,用于后面在A中遍历时与A中元素比较;p指向A表,用于p=p->next 在A表中遍历;pre指针是为了当p遍历到A表末尾之后,用pre指向A表的最后一个结点。定义pre后记得给它分配内存空间。总体大循环while(B), 小循环while(p&&p->data!=s->data),  跳出小循环之后用if判断 p 是否为空。遍历A表结束 p非空 说明A表中有与s->data相同的元素,p最终为NULL,说明A表中没有与s->next相同的元素,此时pre指向A表最后一个结点,将s结点插在a表末尾。

#include<stdio.h>

typedef struct LNode {
	char data;
	struct LNode *next;
}LNode,*LinkList;

void CreateList_L(LinkList &L, char a[], int n)
{
	int i;
	LNode *s;
	L = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		s = new LNode;
		s->data = a[i];
		s->next = L;
		L = s;
	}
}

void union_L(LinkList &A, LinkList &B)
{
	//将B表中所有在A表中不存在的元素都插入到A表中 同时释放B中多余结点
	if (!A)   //如果A为空表 则直接用A表替换B表
		A = B;
	else
	{
		LNode *s;  //s指向B的头结点,用于后面在A中遍历时与A中元素比较
		LNode *p;  //p指向A表,用于p=p->next 在A表中遍历
		LNode *pre; //
		pre = new LNode;
		while (B)
		{
			s = B;
			B = B->next;
			p = A;  //进入每次遍历A表前都要让p重新指向A表第一个结点
			while (p&&p->data != s->data)
			{
				pre = p;   //该步骤目的是当p遍历到A表末尾之后,用pre指向A表的最后一个结点
				p = p->next;
			}
			if (p)   //遍历A表结束 p非空 说明A表中有与s->data相同的元素
				delete s;    //删除
			else       //遍历A表,p最终为NULL,说明A表中没有与s->next相同的元素
			{
				pre->next = s;   //此时pre指向A表最后一个结点 将s插入到A表末尾
				s->next = NULL;
			}
		}
	}
}

void main()
{
	char a[6] = { 'a','b','c','d','e','f' };
	char b[5] = { 's','a','t','e','w' };
	LinkList A, B;
	LNode *p;
	CreateList_L(A, a, 6);
	CreateList_L(B, b, 5);
	union_L(A, B);
	printf("处理后A表为:");
	for (p = A; p != NULL; p = p->next)
		printf("%c ", p->data);
}

本笔记所依据的教材为严薇敏版的《数据结构及应用算法教程》

所有代码在Visual Studio 2017上均可正常运行

如有错误欢迎指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值