合并前
合并后
具体思路:
定义一个指针p指向LA的头节点 使其遍历到最后一个节点 (p->pNext ! = LA)
定义一个指针q指向LB的头节点 使其遍历到最后一个节点 (p->pNext ! = LB)
LA尾节点指向LB首节点(第一个有效数据的节点) (p->pNext = LB-pNext)
释放掉LB的头节点(free(LB))
此时q->pNext 指向的是之前被释放掉LB尾节点 将q->pNext指向LA的头节点那么就又变成了循环单链表 (q->pNext = LA->pNext)
具体实现代码如下
/*
File name: Example.cpp
Description: 有两个带头节点的循环单链表LA,LB,编写一个算法:
将两个循环单链表合并成一个循环单链表,其头指针为LA。
Author: Yang_Jiang
Date: 2018年10月13日
Compiler:Visual Studio 2008
*/
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
typedef struct Student
{
int id; //数据域
struct Student* pNext; //指针域
}NODE,*PNODE;
// NODE 等价于 struct Student
// PNODE 等价于 struct Student*
//函数声明
PNODE create_linlist(int ); //创建链表
void traverse_linlist(PNODE ); //遍历链表
PNODE merge_linlist(PNODE , PNODE);//合并链表
int main()
{
//创建循环单链表LA,LB
PNODE LA = create_linlist(2);
PNODE LB = create_linlist(2);
//合并后的LA
PNODE P = merge_linlist(LA,LB);
traverse_linlist(P);
return 0;
}
/*
函数名:create_linlist();
参数:int len
初始条件:暂无
功能:给定长度,创建出循环单链表
返回值:PNODE
*/
PNODE create_linlist(int len )
{
PNODE pHead = (PNODE) malloc(sizeof(NODE) ); //分配一个不存放有效数据的头节点
if( NULL == pHead)
{
exit(-1); //动态内存分配失败,程序终止!
}
else
{
PNODE Tail = pHead;
Tail->pNext = NULL;
//srand((unsigned)time(NULL)); //调用系统的时间,使得随机数分配不一样
for(int i=0; i<len; i++)
{
PNODE pNew = (PNODE) malloc(sizeof(NODE));
if( NULL == pNew)
{
exit(-1);
}
pNew->id = rand() % 1000; //在0-10000之间随机找数字存放
Tail->pNext = pNew;
pNew->pNext = NULL;
Tail = pNew;
}
Tail->pNext = pHead; //尾指针指向头节点,使其变成一个循环单链表
//Tail->pNext = pHead->pNext;
//如果写成这样,那么就是指向了头指针,即第一个有效数据
}
return pHead;
}
/*
函数名:traverse_linlist();
参数:PNODE pS
初始条件:链表非空
功能:遍历链表
返回值:暂无
*/
void traverse_linlist(PNODE pS)
{
PNODE pre = pS->pNext;
while( pre != NULL)
{
printf("%d\t",pre->id);
pre = pre->pNext;
}
}
/*
函数名:merge_linlist();
参数:PNODE LA , PNODE LB
初始条件:LA和LB都是循环单链表
功能:合并循环单链表
返回值:PNODE
*/
PNODE merge_linlist(PNODE LA, PNODE LB )
{
PNODE p = LA;
PNODE q = LB;
while( p->pNext != LA ) //因为是一个循环单链表 只有让他不等于头节点才代表最后一个节点
{
p = p->pNext; //LA遍历到最后一个节点
}
while( q->pNext != LB ) //因为是一个循环单链表 只有让他不等于头节点才代表最后一个节点
{
q = q ->pNext; //LB遍历到最后一个节点
}
p->pNext = LB->pNext;
free(LB);
LB = NULL;
q->pNext = LA->pNext;
return LA;
}
/*
总结
要注意:
Tail->pNext = pHead; //尾指针指向头节点,使其变成一个循环单链表
Tail->pNext = pHead->pNext; //如果写成这样,那么就是指向了头指针,即第一个有效数据
判断是最后一个节点的条件就是 如果链表指向了头节点 就 退出循环 此时肯定指向的是尾节点
本程序在Visual Studio 2008编译通过,文件是.cpp文件,代码的写法有点不规范,既有C语言
语法也包含了C++语法 望海涵。
*/