链表

//
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define PRINT printf("%c,",p->data); //宏定义对字符串中的字符不替换  不能写为#define PRINTTYPE %c 然后使用printf("PRINTTYPE,",p->data);

typedef char TYPE;
typedef struct Lnode{
	TYPE data;
	struct Lnode *next;//c语言必须加上struct  不能写成Lnode *next(c++可以这样用)
}Node,*pNode;

//1.初始化链表
pNode init_linklist(void)
{
	pNode p=(pNode)malloc(sizeof(Node));
	if(p==NULL)
	{
		printf("fail to init link list!\n");
		exit(0);
	}
	else
	{
		p->next=NULL;
	}
	return p;
}
//2.建立链表
int creat_linklist(pNode pHead)
{
	TYPE c;
	pNode p1=pHead,p2;
	while((c=fgetc(stdin))!=EOF)//只要ctrl+Z(EOF)前面有东西,那么前面的东西读入缓存区,EOF和后面的直到回车(包括回车)被丢弃,只有EOF前面为空才能正确读到EOF,fgetc(s)返回EOF(NULL)
	{
		if(c==','||c=='\n')
			continue;
		p2=(pNode)malloc(sizeof(Node));//p2必须在前面定义  不能写成pNode p2=(pNode)malloc(sizeof(Node));
		if(p1==NULL)
		{
			printf("fail to creat link list!\n");
			exit(0);
		}
		else
		{
			p2->data=c;
			p1->next=p2;
			p1=p2;
		}
	}
	p1->next=NULL;
	return 0;
}
//3.遍历链表
void print_linklist(pNode pHead)
{
	pNode p=pHead->next;
	while(p!=NULL)
	{
		PRINT;
		p=p->next;
	}
	printf("\n");
}
//4.在链表第pos个位置(头结点算第0个位置)插入一个数据data,成功返回0,失败返回-1
int insert_linklist(pNode pHead,TYPE data,int pos)
{
	int i=0;
	pNode p1=pHead,p2,p3;
	if(pos<1)
	{
		printf("wrong position!\n");
		return -1;
	}
	while(i<pos-1)
	{
		p1=p1->next;
		i++;
	}
	p2=(pNode)malloc(sizeof(Node));
	if(p2==NULL)
	{
		printf("fail to allocate memory!\n");
		return -1;
	}
	p3=p1->next;
	p1->next=p2;
	p2->data=data;
	p2->next=p3;
	return 0;
}
//5.删除链表中pos位置的元素,pos意义同上,返回值同上
int delete_linklist(pNode pHead,int pos)
{
	int i=0;
	pNode p=pHead;
	if(pos<1)
	{
		return -1;
	}
	while(i<pos-1)
	{
		p=p->next;
		i++;//不要忘记
	}
	if(p->next==NULL)
	{
		return -1;
	}
	p->next=p->next->next;
	return 0;
}

//6.判断链表是不是有环,有环返回1,没环返回0,若有环,打印入口pos和环长cycle_len
int find_cycle(pNode pHead)
{
	int i=0,inlet=0,cycle_len=0;
	pNode p_slow=pHead;
	pNode p_fast=pHead;
	pNode p_meet;
	while(p_slow!=NULL&&p_fast!=NULL&&p_fast->next!=NULL)//p_fast->next!=NULL
	{
		p_slow=p_slow->next;
		p_fast=p_fast->next->next;
		if(p_slow==p_fast)//此处相遇时公共指针是指向相遇点的指针
		{
			printf("find cycle\n");
			p_meet=p_slow;
			p_slow=pHead;//这里p_slow重新使用确定入口
			while(p_slow!=p_meet)
			{
				p_slow=p_slow->next;
				p_meet=p_meet->next;
				inlet++;//这次相遇是两个指针都是公共节点的next指针
			}
			printf("inlet=%d\n",inlet);//打印inlet序号
			p_meet=p_meet->next;
			while(p_meet!=p_slow)//计算环长
			{
				cycle_len++;
				p_meet=p_meet->next;
			}
			printf("cycle length=%d\n",cycle_len);
			return 1;
		}
	}
	printf("find no cycle!\n");
	return 0;
}
//7.链表逆序
void reverse_linklist(pNode pHead)
{
	pNode p,q,temp1,temp2;
	p=pHead->next;
	q=p->next;
	p->next=NULL;//不能忘
	while(q!=NULL)
	{
		temp1=p;
		p=q;
		temp2=q->next;
		q->next=temp1;
		q=temp2;//注意逻辑
	}
	pHead->next=p;
}
//8.两个链表是否相交 遍历到最后看是否相等
//9.注销掉链表
void destroy_linklist(pNode pHead)
{
	pNode p=pHead,temp;
	while(p!=NULL)
	{
		temp=p;
		p=p->next;
		free(temp);
	}
}
void main(void)
{
	pNode temp;
	TYPE c=(TYPE)0xff;
	pNode pHead=init_linklist();
	temp=pHead;
	creat_linklist(pHead);
	print_linklist(pHead);
	if(insert_linklist(pHead,c,1)<0)
	{
		printf("insert, fault!\n");
	}
	print_linklist(pHead);
	delete_linklist(pHead,4);
	print_linklist(pHead);
	reverse_linklist(pHead);
	print_linklist(pHead);
	find_cycle(pHead);
	while(temp->next!=NULL)//建立一个环
	{
		temp=temp->next;
	}
	temp->next=pHead;
	find_cycle(pHead);
	temp->next=pHead->next->next;
	find_cycle(pHead);
	temp->next=NULL;//删除环才能注销链表
	destroy_linklist(pHead);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值