C语言实现环形链表

来源:互联网 发布:java nio io 区别 编辑:程序博客网 时间:2024/05/16 12:13

虽然现在开发多用Java了,闲着没事拿指针来练练手还是挺有意思的。约瑟夫的问题的解决方案有很多,可以用一个循环10不到解决,但要推导出一个公式;用一维数组加两个循环也可以,这种删除一个数据,后面元素的下标都要跟着变,不太可取。

#include<stdio.h>#include<stdlib.h>typedef struct Linknode{int data;struct Linknode *pNext;}node,*PNODE;//尾部插入PNODE addback(PNODE phead,int data){PNODE pnew= (PNODE)malloc(sizeof(node));pnew->data=data;if(phead==NULL){//一个节点的环 phead=pnew;pnew->pNext=phead;}else{//多个节点PNODE p=phead;while(p->pNext!=phead){//循环到尾部 p=p->pNext;} p->pNext=pnew;//链接到新的节点pnew->pNext=phead;//头尾相连 }return phead;}//头部插入PNODE addfront(PNODE phead,int data){PNODE pnew=((PNODE)malloc(sizeof(node)));pnew->data=data;//一个节点的环 if(phead==NULL){phead=pnew;pnew->pNext=phead;}else{//多个节点PNODE p=phead;while(p->pNext!=phead){//循环到尾部 p=p->pNext;} p->pNext=pnew;pnew->pNext=phead;phead=pnew;}return phead;} void showall(PNODE phead){printf("----------------showall-----------------\n");if(phead==NULL){return;}else if(phead->pNext==phead){//只有一个节点printf("%d,%p,%p",phead->data,phead,phead->pNext); }else{PNODE p=phead;while(p->pNext!=phead){  printf("\n%d,%p,%p",p->data,p,p->pNext);   p=p->pNext;}printf("\n%d,%p,%p",p->data,p,p->pNext); //补充相等的情况 }}PNODE findfirst(PNODE phead,int data){//找到第一个对应值为data的结点 if(phead==NULL){  return NULL;}else if(phead->pNext==phead){//只有一个节点if(phead->data==data){  return phead; }}else{PNODE p=phead;while(p->pNext!=phead){if(p->data==data){return phead;}   p=p->pNext;}if(p->data==data){return phead;}}} PNODE deletefirst(PNODE phead,int data,PNODE* ppNext){//删除第一个对应值为data的结点 PNODE p1=NULL;PNODE p2=NULL;p1=phead;while(p1->pNext!=phead){if(p1->data==data){break;}else{p2=p1;p1=p1->pNext;}}if(p1!=phead){p2->pNext=p1->pNext;*ppNext=p1->pNext;free(p1);}else{//刚好是头结点 PNODE p=phead;while(p->pNext!=phead){p=p->pNext;}phead=phead->pNext;*ppNext=p1->pNext;free(p1);p->pNext=phead;}return phead;}int getnum(PNODE phead){//计算结点的个数   if(phead==NULL){  return 0;}else if(phead->pNext==phead){//只有一个节点return 1;}else{int i=1;PNODE p=phead;while(p->pNext!=phead){  i++;  p=p->pNext;}return i;}}//如果存在结点值为finddata的结点,则在其前面插入data PNODE insertfirst(PNODE phead,int finddata,int data){PNODE p1=NULL;PNODE p2=NULL;p1=phead;while(p1->pNext!=phead){if(p1->data==finddata){break;}else{p2=p1;p1=p1->pNext;}}PNODE pnew=((PNODE)malloc(sizeof(node)));pnew->data=data;if(p1!=phead){pnew->pNext=p1;p2->pNext=pnew;}else{//刚好是头结点 PNODE p=phead;while(p->pNext!=phead){//循环到尾部 p=p->pNext;} p->pNext=pnew;pnew->pNext=phead;phead=pnew;}return phead;}main(){//printf("node有%d字节\n",sizeof(node));//printf("PNODE有%d字节\n",sizeof(PNODE));PNODE phead=NULL;printf("----------------addfront-----------------\n");for(int i=0;i<5;i++){phead=addfront(phead,i);//插入数据 }showall(phead);//printf("\n----------------addback-----------------\n");//phead=NULL;//for(int i=0;i<5;i++){//phead=addback(phead,i);//插入数据 //}//showall(phead);////printf("\n---- findfirst(找到第一个值为3的结点)-----------------\n");//PNODE pfind=findfirst(phead,3);//pfind->data=77777;//showall(phead);////printf("\n------deletefirst(删除值为2的结点)-----------------\n");//phead=deletefirst(phead,2);//showall(phead);////printf("\n------insertfirst(在结点为4的前面插入999999999)-----------------\n");//phead=insertfirst(phead,4,999999999);//showall(phead);    printf("\n\n\n");    //约瑟夫问题PNODE p=phead;while(getnum(phead)!=1){for(int i=1;i<=3;i++){p=p->pNext;}phead=deletefirst(phead,p->data,&p);//删除之后p要从下一个结点继续,所以需有第 3个参数改变其地址 printf("\n");showall(phead);} printf("\n");printf("最后剩下的是%d\n",phead->data);}



0 0
原创粉丝点击