数据结构之循环链表

循环链表

#include<stdio.h>

#include<stdlib.h>

typedef struct stu

{

int data;

struct stu *next;

}node;

node *plst()

{

node *head,*tail,*p;

head=tail=p=NULL;

int x;

char f;

while(1)

{

scanf("%c",&f);

x=f-'0';

if(f=='\n')

break;

p=(node *)malloc(sizeof(node));

p->data=x;

p->next=NULL;

if(head==NULL)

{

head=tail=p;

}

else

{

 

node *r=head;

node *pre=NULL;

while(r)

{

if(x<r->data)

break;

else

{

pre=r;

r=r->next;

}

}

if(r==head)

{

p->next=head;

head=p;

}

else if(r==NULL)

{

tail->next=p;

tail=p;

}

else

{

pre->next=p;

p->next=r;

}

}

}

tail->next=head;//循环链表的创建

return head;

}

void print(node *A)

{

if(A)

{

node *head=A;

do

{

printf("%d",A->data);

A=A->next;

}while(A!=head);

}

printf("\n");

}//打印循环链表用do-while

node * findlast(node *A)

{

if(A)

{

node *head=A;

while(A->next!=head)

{

A=A->next;

}

return A;

}

}//找到循环链表的“尾”

node *deletall(node *A,int x)

{

if(A)

{

node *r=A;

node *pre=findlast(A);

node *tail=pre;

do

{

if(r->data==x)

{

while(A->data==x&&A>next!=A)//r等于A的情况

{

A=A->next;

tail->next=A;

r->next=NULL;

free(r);

r=A;

/*tail->next=r->next;

r->next=NULL;

free(r);

r=tail->next;*/为什么这样不可以,而且会出现段错误?

}

if(A->data==x)

{

free(A);

A=NULL;

return NULL;

}

if(r!=A)

{

pre->next=r->next;

r->next=NULL;

free(r);

r=pre->next;

}

}

else

{

pre=r;

r=r->next;

}

}while(r!=A);

}

return A;

}//删除链表所有为x的值

int main (void)

{

node *A=plst();

int x;

scanf("%d",&x);

node *B=deletall(A,x);

print(B);

/*print(deletall(A,x));*/这样也可以打印

return 0;

}

 


 

 

#include<stdio.h>

#include<stdlib.h>

typedef int ElementType;

typedef struct node

{

ElementType data;

struct node *next;

}Node;

Node *Create_List(void)

{

Node *head,*tail,*p;

head = tail = p = NULL;

ElementType x;

while(1)

{

scanf("%d",&x);

if(x == 0)

break;

 

p = (Node *)malloc(sizeof(Node));

p->data = x;

p->next = NULL;

if(head == NULL)

{

head = tail = p;

tail->next = head;

}

else

{

Node *r = head;

Node *pre = tail;

do

{

if(r->data > x)

break;

else

{

pre = r;

r = r->next;

}

}while(r != head);

/*

此时结束while循环有两个条件,一个条件时r == head

另外一个条件时r != head ,但是r ->data > x 的。

我们需要根据这两种情况去分析到底应该采用哪种插入的方式

如果是 r == head, 那么有可能是一进来满足if语句就出去了,那么

此时应该采用头插法,也有可能是遍历完了整个链表都没有找到(r == head)

那么此时应该采用尾插法

剩下的一种情况就是插入中间的情况了,采用和单链表一样的插入方式

*/

if(r != head)//插入中间

{

pre->next = p;

p->next = r;

}

else//头尾

{

if(r->data > x) //头插法

{

p->next = head;

head = p;

tail->next = head;

}

else //尾插法

{

tail->next = p;

tail = p;

tail->next = head;

}

}

 

}

}

return head;

}

void PrintList(Node *list)

{

if(list)//保证list不为空

{

Node *head = list;

do

{

printf("%d\t",list->data);

list = list->next;

}while(list != head);

}

printf("\n");

}

Node *find_last(Node *list)

{

if(list)

{

Node *head = list;

while(list->next != head)

list = list->next;

}

return list;

}

Node *delete_all_num(Node *list,ElementType num)

{

if(list)

{

Node *r = list;

Node *pre = find_last(list);

Node *tail = pre;

do

{

if(r->data == num)

{

/*

while 循环的前面一个条件是为了解决删除最后一个节点时存在的段错误

所以只剩下一个节点的时候我们分开处理

*/

while(list->next !=list && list->data == num)

{

list = list->next;

tail->next = list;

r->next = NULL;

free(r);

r = list;

}

/*如果只剩下最后一个节点而且节点的值也等于你要删除的那个值*/

if(list->data == num)

{

free(list);

list = NULL;

return NULL;

}

if(r != list) //删除的是尾巴和中间

{

pre->next = r->next;

r->next = NULL;

free(r);

r = pre->next;

}

}

else

{

pre = r;

r = r->next;

}

}while(r != list);

}

return list;

}

int main(int argc,char *argv[])

{

Node *list = Create_List();

PrintList(list);

ElementType x;

scanf("%d",&x);

list = delete_all_num(list,x);

PrintList(list);

return 0;

}

 

 

 

判断是否为循环链表

#include<stdio.h>

#include<stdlib.h>

struct stu

{

int data;

struct stu *next;

};

typedef struct stu node;

node *plmmnb()

{

  node *head,*tail,*p;

  head=tail=p=NULL;

  int x;

  while(1)

  {

  scanf("%d",&x);

  if(x==0)

  break;

  p=(node *)malloc(sizeof(node));

  p->data=x;

  p->next=NULL;

  if(head==NULL)

  {

head=tail=p;

  }

  else

  {

tail->next=p;

tail=p;

  }

  }

  if(head)

  tail->next=head;/*如果什么都不输入,那么head等于NULL,不会连接成循环链表,否则输入东西,会成循环列表*/

  return head;

}

void panduan(node *B)

{

node *p,*q;

p=q=B;

while(q)

{

p=p->next;

q=q->next;

q=q->next;

if(p==q)//循环链表p会追上q

break;

}

if(q==NULL)//不是循环链表,跑的快的q会先等于NULL;

{

printf("no\n");

}

else

{

printf("yes\n");

}

}

int main (void)

{

node *B=plmmnb();

panduan(B);

return 0;

}

 

 

 

带头结点的循环链表(报数,123,逢3退出队伍,下一个重新报数,重新从1开始)

#include<stdio.h>

#include<stdlib.h>

struct stu

{

int data;

struct stu *next;

};

typedef struct stu Node;

struct list

{

Node *first;

Node *last;

int count;

};

typedef struct list List;

List * CreateQueue(void)

{

List *l = (List*)malloc(sizeof(List));

l->first = l->last = NULL;

l->count = 0;

return l;

}

List *EnQueue(List *l,int ch)

{

if(l == NULL)

return ;

//l->count=1;

Node *p;

p = (Node *)malloc(sizeof(Node));

p->data = ch;

p->next = NULL;

if(l->first == NULL)

{

l->first = l->last = p;

}

else

{

l->last->next = p;

l->last = p;

//l->count++;

}

l->count++;

l->last->next=l->first;

return l;

}

void chulai(List *l)

{

int i=1;

Node *p = l->first;

Node *pre=NULL;

while(l)

{

       if(i==3)

   {

   pre->next=p->next;

   p->next=NULL;

   free(p);

   p=NULL;

   p=pre->next;

   

   i=1;

   l->count--;

   }

   else

   {

   pre=p;

   p=p->next;

   i++;

   }

  

    if(l->count==1)

{

printf("剩下%d\n",p->data);

break;

}

}

}

int main (void)

{

List *l = CreateQueue();

while(1)

{

int x;

scanf("%d",&x);

if(x==0)

break;

EnQueue(l,x);

}

chulai(l);

return 0;

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值