头文件
#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;
}