//
#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);
}
链表
最新推荐文章于 2023-09-12 18:07:10 发布