c++链表的实现

本文详细介绍了链表的基本操作,包括创建、逆置、排序、有序链表合并及循环检测。通过随机生成样本序列进行实践验证,展示了排序、逆置和合并后的链表状态,同时演示了如何检测链表是否存在循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
	Author:  Jacky Ma
	Date  :  23th,May,07
*/

/*
主要实现:
	1 链表的创建,
	2 逆置
	3 排序
	4 有序链表的归并
	5 两链表连接
	6 循环链表的判定
*/

#include <iostream>
#include <windows.h>
using namespace std;

//链表节点结构
struct linknode
{
	int data;
	linknode *next;
};

//创建单链表
linknode * create(int n)
{
	linknode *internode = (linknode*)malloc(sizeof(linknode));
	linknode *head = internode;
	internode->data = 0;
	for(int i=1; i<n; i++)
	{
		linknode *midnode = (linknode*)malloc(sizeof(linknode));
		internode->next = midnode;
		midnode->data = i;
		internode = midnode;
	}
	internode->next = NULL;
	return head;
}

//连接链表
linknode * linkcontact(linknode *head1,linknode *head2)
{
	linknode *p = head1;
	linknode *q;
	while(p!=NULL)
	{
		q = p;
		p = p->next;
	}
	q->next = head2;
	return head1 ;
}

//链表逆序
linknode * linkrever(linknode *head)
{
	if(head == NULL)
	{ 
		cout<<"This is an empty link"<<endl; 
		return 0;
	}
	if(head->next == NULL)
	{
		return head;
	}
	linknode *p,*q,*bq;
	p = head;
	q = p->next;
	p->next = NULL;
	while( q != NULL )
	{
		bq = q->next;
		q->next = p;
		p = q;
		q = bq;
	}
	head = p;
	return head;
}

//链表排序用插入法
linknode *linksort(linknode *head)
{
	if(head == NULL)
	{
		cout<<"This is an empty link"<<endl; 
		return 0;
	}
	if(head->next == NULL)
	{
		return head;
	}

	linknode *p,*q,*qb,*hp,*pb;
	p = head; //p指向前链表
	hp = p;
	q = p->next;    //隔离链表,第一个节点首先分离出来
	p->next = NULL; //

	while(q != NULL)
	{
		int i = 0;
		while(p != NULL)
		{
			if(q->data >= p->data)//继续向前走
			{
				pb = p;
				p = p->next;
				i++;
				continue;
			}
			else if(q->data < p->data)//要进行插入
			{
				if(0 == i)              //在插入第一个位置
				{
					qb = q->next;
					q->next = p;
					p = q;
					q = qb;
					hp = p;
				}
				else                 //插入其他位置
				{
					qb = q->next;
					q->next = p;
					pb->next = q;
					q = qb;
					p = hp;
				}
			break;
			}
		}
		if(p==NULL)             //直接插入最后
		{
			qb = q->next;
			q->next = NULL;
			pb->next = q;
			q = qb;
			p = hp;
		}
	}
	head=hp;
	return head;
}

//有序单链表合并后有序
linknode * linkmerge(linknode *head1, linknode *head2)
{
	if(head1==NULL||head2==NULL)
	{
		cout<<" the links are empty"<<endl; 
		return 0;
	}
	linknode *p = head1;
	linknode *q = head2;
	linknode *bp;//纪录p的前一个节点
	linknode *bq;//记录q后的一个节点
	linknode *headp;
	if(q->data < p->data)//插入第一要特殊处理只可能有一个插入第一个
	{
		bq = q->next;
		q->next = p;
		p = q;
		q = bq;
	}

	headp = p;
	while(q!=NULL && p!=NULL)
	{
		if(p->data <= q->data)
		{
			bp = p;
			p = p->next;
			continue;
		}
		else
		{
			bq = q->next;
			q->next = p;
			bp->next = q;
			p = q;
			q = bq;
		}
	}
	if(q == NULL)
	{
		NULL;
	}
	else if(p == NULL)
	{
		bp->next = q;
	}
	cout<<"合并完成!"<<endl;
	return  headp;
}

//判断链表是否有环
bool linkcir(linknode *str)
{
	linknode *p = str;
	linknode *q = str->next;
	while(q != NULL)
	{
		if(p == q)
		{
			cout<<"链表中存在环被发现"<<endl;
			return true;
		}
		q = q->next->next;
		p = p->next;
	}
	return false;
}

//输出单链表的值
void printlinkdata( linknode  *node)
{ 
	return ;
	linknode *p = node;
	while(p != NULL)
	{
		cout<<p->data<<" ";
		p = p->next;
	}
	cout<<endl;
}

int main()
{
	const int L1 = 500;
	const int L2 = 500;
	const int L3 = L1 + L2;
	linknode *linkhead1=create(L1);
	linknode *linkhead2=create(L2);
	linknode *linkhead3=create(L3);
	linknode *p1,*p2,*p3;
	p1=linkhead1;
	p2=linkhead2;
	p3=linkhead3;
	srand( GetTickCount() );//产生种子,每一次序列都不相同
	while(p1!=NULL)
	{
		p1->data = rand()%10000+1; //随机产生样本序列
		p1 = p1->next;
	}

	while(p2 != NULL)
	{
		p2->data = rand()%10000+1; //随机产生样本序列
		p2 = p2->next;
	}

	while(p3!=NULL)
	{
		p3->data = rand()%10000+1; //随机产生样本序列
		p3 = p3->next;
	}

	linknode *pinter1, *pinter2, *pinter3, *pinter4;
	cout<<"链表1排序前序列"<<endl;
	printlinkdata(linkhead1);
	cout<<"链表1排序后序列     ";//验证排序函数
	DWORD l1 = GetTickCount();
	pinter1 = linksort(linkhead1);
	cout<<GetTickCount()-l1<<endl;
	printlinkdata(pinter1);
	cout<<"链表2原始序列"<<endl;
	printlinkdata(linkhead2);
	cout<<"链表2逆置后序列";//验证逆置位函数
	l1 = GetTickCount();
	pinter2 = linkrever(linkhead2);
	cout<<GetTickCount()-l1<<endl;
	printlinkdata(pinter2);
	cout<<"链表2逆置后排序后序列";
	l1 = GetTickCount();
	pinter2 = linksort(pinter2);
	cout<<GetTickCount()-l1<<endl;
	printlinkdata(pinter2);
	cout<<"链表1,2排序后序列合并后结果";//验证有序序列合并后有序
	l1 = GetTickCount();
	pinter3 = linkmerge(pinter1,pinter2);
	cout<<GetTickCount()-l1<<endl;
	printlinkdata(pinter3);
	cout<<"链表3原始序列"<<endl;
	printlinkdata(linkhead3);
	cout<<"新增链表有序合并后结果";//验证链表连接函数
	l1 = GetTickCount();
	pinter4 = linkmerge(pinter3,linkhead3);
	cout<<GetTickCount()-l1<<endl;
	printlinkdata(pinter4);
	cout<<"新增链表有序合并后结果, 创建一个环"<<endl;
	linknode *p = pinter4->next->next;
	linknode *q = pinter4->next;
	for(int i=0; i<10; i++)
	{
		q = q->next;
	}
	q->next = p;
	//验证判定链表中环存在性
	linkcir(pinter4);
	return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值