数据结构笔记

17、循环链表(解决约瑟夫问题)

1、定义链表

typedef struct _LinkNode {
	int data;
 	struct _LinkNode *next;
}LinkNode,LinkList;

2、初始化链表

bool ListInsert_back(linkList* &L,LinkNode *node){
	LinkNode *last = NULL;
	//防御性编程
	if(!L || !node) return false; //节点和L不能为空
	if(L == L->next ){
		node->next = L;
		L->next = node;
	}else{
		last = L->next;
		while(last->next != L) last = last->next;//定位尾结点
	}
	node->next = L;
	last->next = node;
	return true;
}

3、打印链表

void LinkPrint(LinkList* &L){
	LinkList *p;
	if(!L || L==L->next){
		cout<<"链表为空!"<<endl;
		return;
	}
	p=L->next;
	while(p!=L){
		cout<<p->data<<"\t";
		p=p->next;
	}
	cout<<endl;
}

4、解决约瑟夫问题

bool Joseph(LinkList* &L,int go){  //go 是出列的数字,比如喊道3出列,go=3
	LinkList *p,*q;  //p 用来追踪当前节点,而 q 指向即将被删除的节点
	int i=0,j=0;	// i 表示当前应该淘汰的人的编号,j 是一个计数器,用于跟踪当前遍历到了哪个人。
	int times=0,num=0;//times 记录了已经淘汰了几个人就是循环了几轮(1轮出去一个人),num 存储即将被淘汰人的数据值
	p=L;
	if(!L||p->next==L){
		cout<<"链表为空"<<endl;
		return false;
	}
	if(go<1){
		cout<<"出列口令不能小于1!"<<endl;
		return false;
	}
	do{
		i+=go;
		while(p->next){
			if(p->next!=L)j++;//计数器加一
			if(j>=i)break;//说明结束了一轮,要进行下一轮循环
			p=p->next;
		}
		timer++;
		q = p->next;//临时保存被删结点的地址以备释放空间
		num=q->data;
		
		if(timer==3)cout<<"第三个出圈的编号是"<<num<<endl;		

		p = q->next;//p=p->next->next 删除出列的结点
		delete q;
		LinkPrint(L);
	}while(p->next!=L)
	cout<<"最后一个出圈的是"<<num<<endl;
}

5、主函数

int main(void){
	LinkList *L,*s;
	int i= 0 ;
	if(InitList(L)){
		cout<<"成功初始化一个空的循环链表!"<<endl;
	}else{
		exut(-1);
	}
	cout<<"插入10个元素"<<endl;
	while((++i)<10){
		s = new LinkNode;//生成新的结点
		s->data = i;
		s->node = NULL;
	
		if(ListInsert_back(L,s)){
			cout << "插入成功!" << endl;
		}
		else {
			cout << "插入失败!" << endl;
		}
	}
	cout << "尾插法创建循环链表输出结果:\n";
	LinkPrint(L);
	Joseph(L, 5);
	system("pause");
	return 0;
}

你可能感兴趣的:(笔记,数据结构,笔记,算法,c++,c语言)