单链表的基本操作

#include <iostream>
#include <stdlib.h>
#include <Windows.h>
#include <time.h>
using namespace std;

typedef int dataType;

typedef struct Node{
	dataType data;
	struct Node *next;
}LListNode;
typedef LListNode *pLList;


//使用尾插法,创建一个单链表
pLList CreateLinkList()
{
	pLList head=(LListNode*)malloc(sizeof(LListNode));  //增加一个头结点并为之申请内存空间,并定义和初始化head指向头结点
	head->next=NULL;  //初始化头结点指针域为空
	LListNode *p=NULL;  //定义一个移动指针
	LListNode *r=head;  //定义和初始化尾指针指向头结点
	cout<<"please input num:";
	int num=0,i=1,value;
	cin>>num;
	cout<<"please input data(space):";
	while (i<=num)
	{
		cin>>value;
		p=(LListNode*)malloc(sizeof(LListNode));  //增加一个结点并为之申请内存空间
		p->data=value;
		r->next=p;  //让尾结点指向新结点
		r=p;  //更新尾指针指向尾结点(新结点)
		i++;
	}
	r->next=NULL;  //将尾结点置空
	return head;
}

//使用尾插法,创建一个单链表
pLList CreateLinkList_1_9_order()
{
	pLList head=(LListNode*)malloc(sizeof(LListNode));
	head->next=NULL;
	LListNode *p=NULL;
	LListNode *r=head;
	int num=9,i=1;
	while (i<=num)
	{
		p=(LListNode*)malloc(sizeof(LListNode));
		p->data=i;
		r->next=p;
		r=p;
		i++;
	}
	r->next=NULL;
	return head;
}

//使用尾插法,创建一个单链表
pLList CreateLinkList_1_9_random()
{
	pLList head=(LListNode*)malloc(sizeof(LListNode));
	head->next=NULL;
	LListNode *p=NULL;
	LListNode *r=head;
	int num=9,i=1,value;
	srand(unsigned(time(NULL)));
	while (i<=num)
	{
		value=1+rand()%9;
		p=(LListNode*)malloc(sizeof(LListNode));
		p->data=value;
		r->next=p;
		r=p;
		i++;
	}
	r->next=NULL;
	return head;
}


//输出单链表
void OutPut(pLList l)
{
	LListNode *p=l->next;
	cout<<"LinkList:";
	while(p!=NULL)
	{
		cout<<p->data<<" ";
		p=p->next;
	}
	cout<<endl<<endl;
}

//释放单链表内存
void FreeLinkList(pLList *l)  //传入pLList二级指针
{
	LListNode *p=*l,*temp;  //定义移动指针p,初始化为头指针,指向头结点
	while (p)
	{
		temp=p;
		p=p->next;
		free(temp);
	}
	*l=NULL;
}

//获取链表长度
int GetLListLength(pLList l)
{
	LListNode *p=l->next;
	int i=0;
	while(p)
	{
		i++;
		p=p->next;
	}
	return i;
}

//根据位置查找单链表中的元素,返回结点指针
LListNode* FindValueByLoc(pLList l,int loc)
{
	if (loc<=0)
	{
		return NULL;
	}
	int i=0;
	LListNode *p=l->next;
	p=l->next;
	while(p!=NULL)
	{
		if (i==loc-1)
		{
			return p;
		}
		p=p->next;
		i+=1;
	}
	return NULL;
}

//根据位置查找单链表中的元素,返回结点指针
//LListNode *p=NULL;
//FindValueByLoc(l,3,&p);
//cout<<p->data<<endl;
int FindValueByLoc2(pLList l,int loc,LListNode **p)
{
	if (loc<=0)
	{
		return NULL;
	}
	int i=0;
	(*p)=l->next;
	while((*p)!=NULL)
	{
		if (i==loc-1)
		{
			return 0;
		}
		(*p)=(*p)->next;
		i+=1;
	}
	return -1;
}


//在单链表中的loc位置插入value值
int InsertByLoc(pLList l,int loc,dataType value)
{
	if (loc<=0)
	{
		return -1;
	}
	LListNode *p,*s;
	p=FindValueByLoc(l,loc-1);  //查找指向第loc个位置元素的前驱的指针
	if (p)
	{
		s=(LListNode*)malloc(sizeof(LListNode));   //在loc位置创建一个新结点并申请内存空间
		s->data=value;
		s->next=p->next;
		p->next=s;
	}
	return 0;
}

//删除单链表中loc位置的元素
int DeleteByLoc(pLList l,int loc)
{
	if (loc<=0)
	{
		return -1;
	}
	LListNode *p,*temp;
	p=FindValueByLoc(l,loc-1);  //查找指向第loc个位置元素的前驱的指针p
	if (p)
	{
		temp=p->next;  //指针temp指向第loc个元素
		p->next=p->next->next;
		free(temp);
	}
	return 0;
}

//删除所有值为value的元素
int DeleteAllValue(pLList l,dataType value)
{
	LListNode *p=l->next,*temp;  //令指针p指向第一个结点
	LListNode *pre=l;  //令指针pre为p的前驱
	while(p)
	{
		if (p->data==value)
		{
			temp=p;
			pre->next=p->next;
			p=p->next;
			free(temp);
		}else{
			pre=p;
			p=p->next;
		}
	}
	return 1;
}

//删除单链表中最小值(唯一)
int DeleteMin(pLList l)
{
	if (!l->next)
	{
		cout<<"null list"<<endl;
		return 0;
	}
	LListNode *preMin=l;  //定义min指针的前驱
	LListNode *min=l->next;  //指向最小值的指针,初始化指向第一个结点
	LListNode *preP=l->next->next;  //指针p的前驱
	LListNode *p=l->next->next;  //定义一个移动指针,初始化指向第二个结点
	while(p)
	{
		if (p->data<min->data)
		{
			preMin=preP;
			min=p;
		}
		preP=p;
		p=p->next;
	}
	preMin->next=min->next;
	free(min);
	return 1;
}

//链接两个单链表
int ConnectTwoLList(pLList a,pLList b)
{
	LListNode *pa=a,*pb=b->next;
	while (pa->next)
	{
		pa=pa->next;
	}
	pa->next=pb;
	free(b);
	b=NULL;
	return 1;
}

//逆向输出单链表--递归
void OutputReverse(pLList l)
{
	LListNode *p=l->next;  //定义一个移动指针p指向第一个结点
	if (p==NULL)
	{
		return;
	}
	OutputReverse(p);
	cout<<p->data<<" ";
}

//删除单链表中值在s和t之间的数据元素
void DeleteST(pLList l,dataType s,dataType t)
{
	LListNode *temp;
	LListNode *pPre=l;
	LListNode *p=l->next;
	while (p)
	{
		if (p->data>s&&p->data<t)
		{
			temp=p;
			pPre->next=p->next;
			p=p->next;
			free(temp);
		}
		else{
			pPre=p;
			p=p->next;
		}
	}
}

//寻找两个单链表的公共结点,公共结点指同一个结点即指针都是指向这个结点
//如果有公共结点,那么最后一个结点必然一样,再从后往前遍历,必然同时在两个链表的倒数第n个位置是同一个结点
//因此从这两个链表的倒数第n个位置同时向后遍历,如果有必然可以找到第一个公共结点
pLList PrintCommonNode(pLList a,pLList b)
{
	int al,bl,diffl;
	LListNode *longList,*shortList;
	al=GetLListLength(a);
	bl=GetLListLength(b);
	if (al>bl)
	{
		longList=a->next;
		shortList=b->next;
		diffl=al-bl;
	}
	else{
		longList=b->next;
		shortList=a->next;
		diffl=bl-al;
	}
	while (diffl--)  //长链表减去长度之差即向前移动n步,使两个表后部齐长
	{
		longList=longList->next;
	}
	while (longList)  //两个链表同时向后边遍历,边比较
	{
		if (longList==shortList)
		{
			return longList;
		}
	}
	return NULL;
}


//对单链表进行奇偶位置分离
void SeparateOddEven(pLList l)  
{
	pLList a=(LListNode*)malloc(sizeof(LListNode));
	pLList b=(LListNode*)malloc(sizeof(LListNode));
	int i=0;  //奇偶标记
	LListNode *p=l->next,*ar=a,*br=b;  //尾指针ar和br始终指向a表和b表的最后一个元素
	a->next=b->next=NULL;
	while(p!=NULL)
	{
		if(i==0)
		{
			ar->next=p;
			ar=p;
			i=1;
		}
		else
		{
			br->next=p;
			br=p;
			i=0;
		}
		p=p->next;
	}
	ar->next=NULL;  //处理尾指针
	br->next=NULL;
	cout<<"奇数";
	OutPut(a);
	cout<<"偶数";
	OutPut(b);
	free(a);
	free(b);
}

int main()
{
	pLList l=CreateLinkList_1_9_random();
	OutPut(l);


	//LListNode *p;
	//if (p=FindValueByLoc(l,3))
	//{
	//	cout<<p->data<<endl;
	//}
	//else{
	//	cout<<"not exist"<<endl;
	//}
	
	//InsertByLoc(l,3,55);
	//OutPut(l);

	//DeleteByLoc(l,3);
	//OutPut(l);

	//DeleteAllValue(l,3);
	//OutPut(l);

	//DeleteMin(l);
	//OutPut(l);

	//pLList l2=CreateLinkList_1_9_random();
	//OutPut(l2);
	//ConnectTwoLList(l,l2);
	//OutPut(l);
	//FreeLinkList(&l2);

	//OutputReverse(l);

	//DeleteST(l,2,6);
	//OutPut(l);

	//cout<<GetLListLength(l)<<endl;

	SeparateOddEven(l);


	FreeLinkList(&l);
	system("pause");
	return 1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

water|water

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值