数据结构第五章:带头结点的链表

Posted 歌咏^0^

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构第五章:带头结点的链表相关的知识,希望对你有一定的参考价值。

一、判断链表 listB 是否是 链表 listA的子链表

/*
四、判断链表 listB 是否是 链表 listA的子链表
思路:1、遍历链表A,在遍历过程中 ,每个结点跟链表B的首结点进行比较
			1)如果相等 
					同时 遍历链表A和遍历链表B
						最后也有两种结果
							
			2)不相等,链表A往下面移动
			
				
*/
bool judge_subList(struct list *listHeadA,struct list *listHeadB)
{
	//1、遍历链表A,在遍历过程中 ,每个结点跟链表B的首结点进行比较
	struct node *pA = listHeadA->head;
	struct node *save = NULL;//记录 两条链表同时遍历时的当前结点的下一个结点
	while(pA)
	{
		//1)如果相等 
		
		if(pA->data == listHeadB->head->data)
		{
			save = pA->next;//保存
			//			同时 遍历链表A和遍历链表B
			//链表A从当前结点pA开始   链表B从首结点开始
			struct node *pB = listHeadB->head;
			
			while(pA && pB)
			{
				if(pA->data != pB->data){
					pA = save;
					break;
				}
				pA = pA->next;
				pB = pB->next;
			}
			if(pB == NULL)
			{
				return true;
			}
		}
		else{
			//2)不相等,链表A往下面移动
			pA = pA->next;
		}		
	}
	
	return false;
}

二、求两条链表的交集。

/*
五、求两条链表的交集。
两个已知有序链表listA 和 listB ,找出值相同的结点,生成一个新的链表(原来的链表不能被破坏),新的链表是有序的,且没有重复的结点

思路:  1、创建新链表的头节点 newHead ,并且初始化
	    2、同时遍历两条链表 ,比较每个结点的大小
				1)如果相等
					a 先判断是否跟上一个值一样,
					b 新建一个结点 并且用相等的值作为初始化数据,插入到新链表中
							b_1  新链表刚开始是空的,新结点就作为数据首结点(从无到有)
							b_2  (从少到多) 使用尾插
					c 同时移动 结点
		3、返回新链表的头节点

*/
struct list* common_of_list(struct list *listHeadA,struct list *listHeadB)
{
	//思路:  1、创建新链表的头节点 newHead ,并且初始化
	struct list *newHead = malloc(sizeof(struct list));
	if(newHead == NULL)
	{
		printf("malloc newHead error\\n");
		return NULL;
	}
	newHead->head = NULL;
	newHead->nodeNumber = 0;
	
	//    2、同时遍历两条链表 ,比较每个结点的大小
	struct node *pA = listHeadA->head;
	struct node *pB = listHeadB->head;
	ElemType save = 0;//记录上一次新链表的值
	
	while(pA && pB) //pA == NULL
	{
		//1)如果相等
		if(pA->data == pB->data)
		{				
			//a 先判断是否跟上一个值一样,
			if(save != pA->data)
			{
				save = pA->data;
				//	b 新建一个结点 并且用相等的值作为初始化数据,插入到新链表中
				struct node *newNode = new_node(newHead,pA->data);
				//b_1  新链表刚开始是空的,新结点就作为数据首结点(从无到有)
				if(newHead->head == NULL)
				{
					newHead->head = newNode;
				}
				else{//b_2  (从少到多) 使用尾插
					//1、遍历新链表,找到尾结点
					struct node *p=newHead->head;
					struct node*pre=NULL;
					while(p)
					{
						pre = p;
						p = p->next;
					}
					//pre就是尾结点
					pre->next = newNode;
				}
			}
			
			//c 同时移动 结点	
			pA = pA->next;
			pB = pB->next;
		}
		else if(pA->data < pB->data)//哪条链表的结点小,就先移动
		{
			pA = pA->next;
		}
		else if(pB->data <pA->data)
		{
			pB = pB->next;
		}
	}


	//	3、返回新链表的头节点
	return newHead;
}

以上是关于数据结构第五章:带头结点的链表的主要内容,如果未能解决你的问题,请参考以下文章

N日一篇——Java实现栈

数据结构-1 带头结点的链表合并

java实现单向循环链表

链表习题-将带头结点的链表进行逆置

带头结点的链表

数据结构第三章:不带头结点的单链表操作