数据结构第3天

单向循环链表(头节点和尾节点形成循环)

创建头节点

Loop* create_loop()
{
	Loop* head=(Loop*)malloc(sizeof(Loop));
	if(head==NULL){
		printf("创建头结点失败\n");
		return NULL;
	}
	head->next=head;
	head->text.len=0;
	return head;
}

从头部插入数据

void insert_loopBefore(Loop* head,dataType data)
{
	Loop* temp=(Loop*)malloc(sizeof(Loop));
	if(temp==NULL){
		printf("创建结点失败\n");
		return;
	}

	temp->text.data=data;

	temp->next=head->next;
	head->next=temp;
	head->text.len++;
	return;
}

从尾部插入数据

void insert_loopAfter(Loop* head,dataType data)
{
	Loop* temp=(Loop*)malloc(sizeof(Loop));
	if(temp==NULL){
		printf("创建结点失败\n");
		return;
	}

	temp->text.data=data;
	Loop* p=head;

	while(p->next!=head){
		p=p->next;
	}
	p->next=temp;
	temp->next=head;
	head->text.len++;

	return;
}

遍历链表

void travel_loopList(Loop* head)
{
	Loop* p=head;
	while(p->next!=head){
		p=p->next;
		printf("%d ",p->text.data);
	}	
	putchar(10);
	return;
}

从头部删除数据

void delete_loopBefore(Loop* head)
{
	if(head==NULL || head->next==head){
		printf("链表错误或链表为空\n");
		return;
	}
	Loop* temp=head->next;
	head->next=head->next->next;
	head->text.len--;

	free(temp);
	temp=NULL;
	return;
}

从尾部删除数据

void delete_loopAfter(Loop* head)
{
	if(head==NULL || head->next==head){
		printf("链表错误或链表为空\n");
		return;
	}

	Loop* p=head;
	while(p->next->next!=head){//找倒数第二个
		p=p->next;
	}
	Loop* temp=p->next;
	p->next=head;
	head->text.len--;

	free(temp);
	return;
}

头文件

#ifndef __LOOPLINK_H__
#define __LOOPLINK_H__

#include <stdlib.h>
#include <stdio.h>

typedef int dataType;
typedef struct loop{
	union{
		int len;
		dataType data;
	} text;
	struct loop* next;
} Loop;

Loop* create_loop();
void insert_loopBefore(Loop* head,dataType data);
void insert_loopAfter(Loop* head,dataType data);

void travel_loopList(Loop* head);

void delete_loopBefore(Loop* head);
void delete_loopAfter(Loop* head);

#endif

主函数体

#include "./03_loopLink.h"

int main(int argc, const char *argv[])
{
	Loop* head=create_loop();
	insert_loopBefore(head,10);
	insert_loopBefore(head,20);
	insert_loopBefore(head,70);
	insert_loopBefore(head,8);

	travel_loopList(head);

	delete_loopBefore(head);
	delete_loopAfter(head);
	travel_loopList(head);
	return 0;
}

双向链表(可以向前访问也可以向后访问)

创建头结点

Bothway* create_bothway()
{
	Bothway* head=(Bothway*)malloc(sizeof(Bothway));
	if(head==NULL){
		printf("创建头结点失败\n");
		return NULL;
	}
	memset(head,0,sizeof(Bothway));
	
	return head;
}

从头部插入数据

void insert_bothwayBefore(Bothway* head,datatype data)
{
	Bothway* temp=(Bothway*)malloc(sizeof(Bothway));
	memset(temp,0,sizeof(Bothway));
	temp->text.data=data;

	if(head->next!=NULL){
	temp->next=head->next;
	head->next=temp;

	temp->next->prev=temp; //如果head后面没有结点,temp->next->prev是空
							//必出段错误
	temp->prev=head;
	}else{
		temp->prev=head;
		head->next=temp;
	}


	head->text.len++;

	return;
}

从尾部插入数据

void insert_bothwayAfter(Bothway* head,datatype data)
{
	Bothway* temp=(Bothway*)malloc(sizeof(Bothway));
	memset(temp,0,sizeof(Bothway));
	temp->text.data=data;

	Bothway* p=head;
	while(p->next!=NULL){
		p=p->next;
	}
	p->next=temp;
	temp->prev=p;

	head->text.len++;
	return;
}

按位置插入数据

void insert_bothwayByPos(Bothway* head,datatype data,int pos)
{
	if(pos>head->text.len+1 || pos<1){
		printf("插入位置不合法\n");
		return;
	}
	Bothway* temp=(Bothway*)malloc(sizeof(Bothway));
	memset(temp,0,sizeof(Bothway));
	temp->text.data=data;

	Bothway* p=head;
	for(int i=0;i<pos-1;i++){ //i从1开始
		p=p->next;
	}
	if(p->next==NULL){ //尾插
	p->next=temp;
	temp->prev=p;

	}else{ //头插
	p->next->prev=temp;
	temp->prev=p;

	temp->next=p->next;
	p->next=temp;
	}
	head->text.len++;
	return;
}

按位置删除数据

void delete_bothwayByPos(Bothway* head,int pos)
{
	if(head==NULL || head->next==NULL){
		printf("链表错误或为空\n");
		return;
	}
	if(pos>head->text.len || pos<1){
		printf("删除位置不合法\n");
		return;
	}
	Bothway* p=head;
	for(int i=0;i<pos-1;i++){
		p=p->next;
	}

	if(p->next==NULL){//尾删
		p->prev->next=NULL;
		free(p);

	}else{//头删
		Bothway* temp=p->next;
		p->next->next->prev=p;
		p->next=p->next->next;
		free(temp);
	}
	head->text.len--;
	return;
}

遍历数据

void travel_bothway(Bothway* head)
{
	Bothway* p=head;
	while(p->next!=NULL){
		p=p->next;
		printf("%d ",p->text.data);
	}
	putchar(10);
	return;
}

从头部删除数据

void delete_bothwayBefore(Bothway* head)
{
	if(head==NULL || head->next==NULL){
		printf("链表错误或为空\n");
		return;
	}
	Bothway* temp=head->next;
	if(head->next->next==NULL){ //尾删
		head->next=NULL;
	}else{ //头删
		head->next=head->next->next;
		temp->next->prev=head;
	}
	head->text.len--;
	free(temp);
	temp=NULL;
	return;
}

从尾部删除数据

void delete_bothwayAfter(Bothway* head)
{
	if(head==NULL || head->next==NULL){
		printf("链表错误或为空\n");
		return;
	}
	Bothway* p=head;
	while(p->next!=NULL){
		p=p->next;
	}
	p->prev->next=NULL; //前一个结点的next
	free(p);

	head->text.len--;
	return;
}

头文件

#ifndef __BOTHWAY_H__
#define __BOTHWAY_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int datatype;

typedef struct bothway{
	struct bothway* prev;
	union{
		int len;
		datatype data;
	} text;
	struct bothway* next;
} Bothway;

Bothway* create_bothway();
void insert_bothwayBefore(Bothway* head,datatype data);
void insert_bothwayAfter(Bothway* head,datatype data);
void insert_bothwayByPos(Bothway* head,datatype data,int pos);
void travel_bothway(Bothway* head);

void delete_bothwayBefore(Bothway* head);
void delete_bothwayAfter(Bothway* head);
void delete_bothwayByPos(Bothway* head,int pos);

#endif

主函数体

#include "./03_bothway.h"

int main(int argc, const char *argv[])
{
	Bothway* head=create_bothway();
	insert_bothwayBefore(head,10);
	insert_bothwayBefore(head,20);
	insert_bothwayAfter(head,30);
	insert_bothwayAfter(head,40);
	insert_bothwayByPos(head,50,1);
	insert_bothwayByPos(head,60,5);
/*	travel_bothway(head);

	delete_bothwayBefore(head);
	delete_bothwayBefore(head);
	delete_bothwayAfter(head);
	delete_bothwayAfter(head);
	delete_bothwayByPos(head,1);
	travel_bothway(head);
*/
	return 0;
}

双向循环链表(头节点和尾节点形成循环)

创建头结点

Loop* create_loopBothway()
{
	Loop* head=(Loop*)malloc(sizeof(Loop));
	if(NULL==head){
		printf("创建结点失败\n");
		return NULL;
	}
	memset(head,0,sizeof(Loop));
	head->prev=head;
	head->next=head;
	return head;
}

判断头节点是否正确

int list_isTrue(Loop* head)
{
	if(NULL==head){
		printf("链表错误\n");
		return 1;
	}
	return 0;
}

从头部插入数据

void insert_loopBothwayBefore(Loop* head,datatype data)
{
	if(list_isTrue(head)) return;
	Loop* temp=(Loop*)malloc(sizeof(Loop));
	if(NULL==temp){
		printf("创建结点失败\n");
		return;
	}
	memset(temp,0,sizeof(Loop));
	temp->text.data=data;
	if(head->next==head){ //尾插
		head->next=temp;
		temp->next=head;
		temp->prev=head;
		head->prev=temp;
	}else{ //头插
		temp->next=head->next;
		head->next=temp;
		temp->next->prev=temp;
		temp->prev=head;
	}
	head->text.len++;

	return;
}

从尾部插入数据

void insert_loopBothwayAfter(Loop* head,datatype data)
{
	if(list_isTrue(head)) return;
	Loop* temp=(Loop*)malloc(sizeof(Loop));
	if(NULL==temp){
		printf("创建结点失败\n");
		return;
	}
	memset(temp,0,sizeof(Loop));
	temp->text.data=data;

	Loop* p=head;
	while(p->next!=head){
		p=p->next;
	}
	temp->next=p->next;
	temp->prev=p;
	p->next=temp;

	head->text.len++;
	return;
}

按位置插入数据

void insert_loopBothwayBypos(Loop* head,datatype data,int pos)
{
	if(list_isTrue(head)) return;
	if(pos<1 ||pos>head->text.len+1){
		printf("插入位置不合法\n");
		return;
	}
	Loop* temp=(Loop*)malloc(sizeof(Loop));
	if(NULL==temp){
		printf("创建结点失败\n");
		return;
	}
	memset(temp,0,sizeof(Loop));
	temp->text.data=data;
	
	Loop* p=head;
	for(int i=0;i<pos-1;i++){
		p=p->next;
	}
	if(p->next==head){ //尾插
		temp->next=head;
		temp->prev=p;
		p->next=temp;
	}else{ // 头插
	p->next->prev=temp;
	temp->prev=p;

	temp->next=p->next;
	p->next=temp;
	}
	head->text.len++;

	return;
}

遍历数据

void travel_loopBothway(Loop* head)
{
	Loop* p=head;
	while(p->next!=head){
		p=p->next;
		printf("%d ",p->text.data);
	}
	return;
}

从头部删除数据

void delete_bothwayBefore(Loop* head)
{
	if(list_isTrue(head)) return;
	Loop* temp=head->next;
	if(temp->next==head){ //尾删
		head->next=head;
		head->prev=head;
	}else{ //头删
		head->next=temp->next;
		temp->next->prev=head;
	}
	free(temp);
	temp=NULL;
	head->text.len--;
	return;
}

从尾部删除数据

void delete_bothwayAfter(Loop* head)
{
	if(list_isTrue(head)) return;
	Loop* p=head;
	while(p->next!=head){
		p=p->next;
	}
	p->prev->next=head;
	free(p);
	head->text.len--;
	return;
}

按位置删除数据

void delete_bothwayByPos(Loop* head,int pos)
{
	if(list_isTrue(head)) return;
	Loop* p=head;
	for(int i=0;i<pos;i++){
		p=p->next;
	}
	if(p->next==head){//尾删
		p->prev->next=head;
	}else{//头删
		p->next->prev=p->prev;
		p->prev->next=p->next;
	}
	free(p);
	head->text.len--;
	return;
}

约瑟夫问题

joseph(约瑟夫)问题

1.设编号分别为:1,2,...,n的n个人围坐一圈。

2.约定序号为k (1sksn) 的人从1开始计数,数到m的那个人出列,

3.他的下一位又从1开始计数,数到m的那个人又出列,依次类推,直到所有人出列为止。

例如,8个人围坐一圈,约定从第3个人开始编号为1,数到第4个人出列。

出列后原来第5个人计算为1.n=8,k=3,m=4,最终出队的结果是6 2 7 4 3 5 18

用单向循环链表来做

void joseph(int n,int k,int m)
{
	//拼装约瑟夫环
	Loop* head=create_loop();
	for(int i=1;i<=n;i++){
		insert_loopAfter(head,i);
	}


	Loop* p=head;
	while(p->next!=head){
		p=p->next;
	}
	p->next=head->next; //形成环
	p=head;//重置指针
	head=head->next;//将头结点置为第一个结点
	free(p);

	p=head;//重置指针到第一个结点
	for(int i=1;i<k;i++){
		p=p->next;
	}
	printf("k=%d\n",p->text.data);

	while(p->next!=p){ //当结点指向自己就说明只剩一个结点
		for(int i=0;i<m-2;i++){ //找到要删除的前一个:-1 从1开始:-1 共-2 
			p=p->next;
		}
		printf("Detele:%d\n",p->next->text.data);
		Loop* temp=p->next;
		p->next=p->next->next;
		free(temp);
		p=p->next;
	}
	printf("Delete:%d\n",p->text.data);
	return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值