循环双链表练习

头文件

#ifndef __SEQ_DUBLOOPLINK__

#define __SEQ_DUBLOOPLINK__

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

typedef int newtype;

typedef struct dublooplink_list
{
	union 
	{
		newtype data;
		int len;
	} Data;
	struct dublooplink_list* next;
	struct dublooplink_list* prev;
}dlll;

//创建头节点
dlll* create_dublooplink_node();
//遍历链表
void show_dublooplink_list(dlll*);
//头插法
void head_insert(dlll* , newtype);
//尾插法

void tail_insert(dlll* , newtype);
//任意位置插入
int index_insert(dlll* , newtype , int);
//头删法
int head_del(dlll* );
//尾删法
int tail_del(dlll* );
//按位置删除
int index_del(dlll* , int);
//清空链表
dlll* clear_dublooplink(dlll*);

//释放链表
void free_dublooplink(dlll** head);
//joseph(约瑟夫)问题
void joseph(dlll** ptr);



#endif

函数实现

#include "./seq_dublooplink.h"


//创建节点
dlll* create_dublooplink_node()
{
	dlll* ptr = (dlll*)malloc(sizeof(dlll));
	memset(ptr,0,sizeof(dlll));
	ptr->next = ptr;
	ptr->prev = ptr;
	return ptr;
}

//遍历链表
void show_dublooplink_list(dlll* ptr)
{
	dlll* head = ptr; 
	for(int i=1;(ptr=ptr->next)!=head;i++)
	{
		if(i%5)
			printf("%d ", ptr->Data.data);
		else
			printf("%d\n", ptr->Data.data);
	}
	putchar(10);
	return;
}


//头插法
void head_insert(dlll* ptr,newtype data)
{
		//创建节点
		dlll* temp = create_dublooplink_node();
		temp->Data.data = data;
		//头插
		ptr->next->prev = temp;	
		temp->next = ptr->next;
		temp->prev = ptr;
		ptr->next = temp;
		ptr->Data.len++;
		return;
}

//尾插法
void tail_insert(dlll* ptr, newtype data)
{
	//创建节点
	dlll* temp = create_dublooplink_node();
	temp->Data.data = data;
	//找到尾节点
	dlll* p = ptr;
	while(p->next!=ptr)	//判断是否到达尾节点
	{
		p = p->next;
	}
	//插入节点
	temp->prev = p;
	temp->next = ptr;
	ptr->prev = temp;
	p->next = temp;
	ptr->Data.len++;
	return;
}

//按位置插入
int index_insert(dlll* ptr, newtype data, int index)
{
	if(index<1)
	{
		printf("位置输入不合法!\n");
		return -1;
	}
	else
	{	
		//创建节点
		dlll* temp = create_dublooplink_node();
		temp->Data.data = data;
		//查找位置
		dlll* p = ptr;
		for(int i=1; i<index && (p=p->next)->next!=ptr; i++);
		//插入数据
		temp->next = p->next;
		p->next = temp;	
		temp->prev = p;
		temp->next->prev = temp;
		ptr->Data.len++;
		return 0;
	}
}
//头删法
int head_del(dlll* ptr)
{
	//判断链表是否为空
	if(ptr->next!=ptr)
	{
		//不为空删除第一个节点
		dlll* p = ptr->next;
		ptr->next = p->next;
		p->next->prev = ptr;
		free(p);
		ptr->Data.len--;
		return 0;
	}
	else
	{
		//为空输出语句并返回-1
		printf("链表为空,无法删除\n");
		return -1;
	}
}
//尾删法
int tail_del(dlll* ptr)
{
	//判断链表是否为空
	if(ptr->next!=ptr)
	{
		//不为空删除最后一个结点
		ptr->Data.len--;			//链表长度减一
		//找到最后一个结点
		dlll* p = ptr;
		while(p->next->next!=ptr)
			p = p->next;
		//删除为结点
		free(p->next);
		p->next = ptr;
		ptr->prev = p;
		return 0;
	}	
	else
	{
		printf("链表为空,无法删除\n");
		return -1;
	}
}
//按位置删除
int index_del(dlll* ptr, int index)
{
	//判断链表是否为空
	if(ptr->next==ptr)
	{
		printf("链表为空,删除失败\n");
		return -1;
	}
	//查找位置结点
	int i;
	dlll* p = ptr->next; 
	for(i=1; i<index && p->next!=ptr; i++)
	{
		p = p->next;
	}
	//判断删除位置是否大于链表长度
	//大于则删除最后一个结点
	if(p->next==ptr)
	{
		if(i<index)
			printf("删除位置超过链表长度,删除最后一个\n");
		p->prev->next = ptr;
		ptr->prev = p->prev;
		free(p);
		ptr->Data.data--;
		return 1;
	}
	//否则就删除对应位置元素
	else
	{

		p->next->prev = p->prev;
		p->prev->next = p->next;
		free(p);
		ptr->Data.len--;
		return 0;
	}
}

//清空链表
dlll* clear_link(dlll* ptr)
{
	while(ptr->next!=ptr)
	{
		head_del(ptr);
	}
	return ptr;
}

//释放链表
void free_link(dlll** head)
{
	clear_link(*head);
	free(*head);
	*head = NULL;
	return;
}



















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值