单链表和循环单链表的基本操作

单链表和循环单链表的基本操作

/**
	2021.8.23
	lkm
	   该项目里面包含单链表操作以及循环单链表操作,
	注意:循环单链表判断条件为p!=L; 
**/
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
	int data;             //数据域 
	struct LNode *next;   //指针域 
}LNode,*LinkList;
//1.头插法建立链表,即将待插入的结点插在第一个位置//
LinkList CreateList( LinkList L,int n)    //--L-- p
{
	LinkList p;
	int i;
	L=(LinkList)malloc(sizeof(LNode));//创建头结点   获取LNode的字段长度,然后强转为Linklist类型
	L->next=NULL;
    for(i=0;i<n;i++)
	{
		p=(LinkList)malloc(sizeof(LNode));//创建新结点、 
		scanf("%d",&(p->data));		
		p->next=L->next;//p的后继等于L的后继 
		L->next=p;//将L的后继是p 		
	}
 return L;
}
//循环单链表用尾插法建立链表,即将待插入的结点插在尾部位置
LinkList CreateList1( LinkList L,int n)   /// --p--L
{
	LinkList p,r;
	int i;
	L=(LinkList)malloc(sizeof(LNode));//创建头结点   获取LNode的字段长度,然后强转为Linklist类型
	L->next=NULL;
	r=L;
    for(i=0;i<n;i++)
	{
		p=(LinkList)malloc(sizeof(LNode));//创建新结点、 
		scanf("%d",&(p->data));	
		
		//将p转为实际头结点	
		p->next=NULL;
		r->next=p;
		r=p; 		
	}
	p->next=L;
 return L;
}
//2.输出链表//
void ShowList(LinkList L,int n)
{
	int i=1;
	LinkList p;
	p=L->next;
	while( p && i<n)  //单链表输出 
	//while( p!=L && i<n) //循环单链表输出链表 
	{
		printf("the data %d is %d\n",i,p->data);
		p=p->next;
		i++;
	}
}
void ShowList1(LinkList L,int n) 
{
	int i=1;
	LinkList p;
	p=L;
	while( p && i<n)  //单链表输出 
	//while( p!=L && i<n) //循环单链表输出链表 
	{
		printf("the data %d is %d\n",i,p->data);
		p=p->next;
		i++;
	}
}
//3.求链表的长//
int Length(LinkList L)
{
  int l=0;
  LinkList p;
  p=L->next;
  while(p)  //单链表  p!=NULL
  //while(p!=L) //循环单链表输出链表长度  p!=L
	{
		l=l+1;
		p=p->next;
	}
   return l;
}
//4.在链表中第i个位置插入值为e结点//
LinkList Insert(LinkList L,int i,int e)
{
	LinkList p,s;
	int j=1;
	p=L;
	while(p && j<i) 
	{
		p=p->next;
		j++;
	}
	s=(LinkList)malloc(sizeof(LNode));
	s->data=e;
	s->next=p->next;
	p->next=s;
 	return L;
}
//5.删除链表中的第i个结点//
LinkList Delete(LinkList L,int i)
{
	LinkList p,q;
	int j=1;
	p=L;
	while(p && j<i)//
	{
		p=p->next;
		j++;
	}
	q=p->next;
	p->next=q->next;
	free(q);
	return L;
}
//6.取出链表中第i个结点的值//
int GetData(LinkList L,int i)
{
	LinkList p;
	int e;
	int j=1;
	p=L->next;
	while(p&&j<i)
	//while(p!=L && j<i) 
	{
		p=p->next;
		j++;
	}
	e=p->data;
	return e;
}
//7.找链表中结点值为d的前驱结点的值//
int Prior(LinkList L,int d)
{
	LinkList p;
	p=L->next;	
	while(p&&p->data!=d)
	//while(p!=L&&p->data!=d)
	{
		p=p->next;
	}
	return p->data;
}
//8.单链表将两个链表合并,返回合并后链表的头结点Hc//
LinkList MergeList(LinkList Ha,LinkList Hb)
{
	LinkList a,b,c;
	LinkList Hc;
	Hc=(LinkList)malloc(sizeof(LNode));
	c=Hc;
	c->next=NULL;
	a=Ha->next;
	b=Hb->next;
	while(a && b )
	{
		if(a->data<=b->data)
		{
			c->next=a;
			c=a;
			a=a->next;
		}
		else {
			c->next=b;
			c=b;
			b=b->next;
		}
	}
	c->next=a?a:b;//若a为NULL,c->next=b,反之亦然。 
	//free(Ha);
	free(Hb);
	return Hc;
}
//9.循环单链表将两个链表合并,此算法采用尾指针首尾相连 
LinkList MergeList1(LinkList Ha,LinkList Hb)
{
	LNode *p; //与下面三行可以替换 
	/**
	LinkList p;
	p=(LinkList)malloc(sizeof(LNode));
    p->next=NULL;
	**/ 
	
    p=Ha->next;  //保存链表Ha的头结点地址 
    Ha->next=Hb->next->next;  //Ha的头结点连到Hb的尾结点 
	Hb->next=p;  //链表Hb的头结点换成链表Ha的头结点 
	return Hb;
		
}
//10.判断链表是否有环
bool hasCycle(LinkList L) {
	
    LinkList p = L;
    LinkList q = L;
    while(q && q->next){
        p = p->next;
        q = q->next->next;
        if (p == q)
            return true;
    }
    return false;
}

//11.反转链表(单链表)
LinkList ReverseList(LinkList L){
	LinkList p,q,temp;
	if(L==NULL){
		return NULL;//链表为空 
	}
	if(L->next==NULL){
		return L;//只有一个节点 
	}
	p=L;
	q=L->next;
	L->next=NULL;	
	while(q!=NULL){
		temp=q->next;
		q->next=p;
		p=q;
		q=temp;
	}
	return p;	
}
//12.反转链表指定区域
LinkList ReversePositionList(LinkList L, int m, int n){
	LinkList r,p,q,temp;
	p=(LinkList)malloc(sizeof(LNode));
	if(L == NULL){//链表为空
		return NULL; 
	}
	if(L->next == NULL) {//只有一个头结点 
		return L;
	}
	p=L;
	r=p;
	int i=1;
	while(r && i<m) {//遍历到m的前一个位置 
		r=r->next;
		i++;
	}
	temp=r->next;
	q=temp->next;
	while(m<n){
		temp->next=q->next;
		q->next=r->next;
		r->next=q;
		q=temp->next;
		m++;
	}
	return p;
}
int main()
{   
	LinkList La,Lb;
	int n,len;
	LinkList pa,pb,pc;//新结点 
	printf("input the length of list a:");
	scanf("%d\n",&n);
	pa=CreateList(La,n);
	len=Length(pa);
	printf("the list length is %d \n",Length(pa));
	ShowList(pa,len+1);
	printf("\n");
	  
	printf("input the length of list b:");
	scanf("%d\n",&n);
	pb=CreateList(Lb,n);
	len=Length(pb);
	printf("the list length is %d \n",Length(pb));
	ShowList(pb,len+1);
	printf("\n");

    printf("pb链表是否有环?0/1 \n");
    printf("%d\n",hasCycle(pb));
    
    //找到链表La的结点值为3的前驱结点并输出//  
	printf("the Prior of %d is %d\n",3,Prior(pa,3)); 
  
    //在链表La的第4个位置插入值为63的结点后输出链表//
	pa=Insert(pa,4,63);
	len=Length(pa);
	printf("链表La的4个位置插入值为63\n");
	printf("the inserted list length is %d \n",Length(pa));
	ShowList(pa,len+1);

    //删除链表Lb的第3个位置的结点后输出链表//
	pb=Delete(pb,3);
	len=Length(pb);
	printf("删除链表Lb的第3个位置的结点\n"); 
	printf("the deleteed list length is %d \n",Length(pb));
	ShowList(pb,len+1);

    //合并链表La、Lb,并输出//
	pc=MergeList(pa,pb);
	len=Length(pc);
	printf("\nthe pc list length is %d \n",Length(pc));
	ShowList(pc,len+1);
	
	//反转指定区域链表
	pc=ReversePositionList(pc,2,3);	
	printf("\npc链表2到3区域反转:\n");
	len=Length(pc);
	ShowList(pc,len+1);
	
	//反转链表
	pc=ReverseList(pc);
	printf("\npc链表反转:\n");
	len=Length(pc);
	ShowList1(pc,len+1);

}

看到最后还不留下你的赞和小钱钱~
在这里插入图片描述

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

傻猴儿

小编,多谢客官留下的赏钱。

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

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

打赏作者

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

抵扣说明:

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

余额充值