码迷,mamicode.com
首页 > 其他好文 > 详细

环形链表

时间:2015-08-31 21:44:17      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

虽然现在开发多用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);

}
	
	

技术分享

技术分享

版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载,请注明出处:http://blog.csdn.net/lindonglian

环形链表

标签:

原文地址:http://blog.csdn.net/lindonglian/article/details/48139695

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!