头文件
#ifndef __SEQ_DUBLINK__
#define __SEQ_DUBLINK__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef int newtype;
typedef struct dublink_list
{
union
{
newtype data;
int len;
} Data;
struct dublink_list* next;
struct dublink_list* prev;
}dll;
//创建头节点
dll* create_dublink_node();
//遍历链表
void show_dublink_list(dll*);
//头插法
void head_insert(dll* , newtype);
//尾插法
void tail_insert(dll* , newtype);
//任意位置插入
int index_insert(dll* , newtype , int);
//头删法
int head_del(dll* );
//尾删法
int tail_del(dll* );
//按位置删除
int index_del(dll* , int);
//清空链表
dll* clear_dublink(dll*);
//释放链表
void free_dublink(dll** head);
//joseph(约瑟夫)问题
void joseph(dll** ptr);
#endif
函数实现
#include "./seq_dublink.h"
//创建节点
dll* create_dublink_node()
{
dll* ptr = (dll*)malloc(sizeof(dll));
memset(ptr,0,sizeof(dll));
ptr->next = NULL;
ptr->prev = NULL;
return ptr;
}
//遍历链表
void show_dublink_list(dll* ptr)
{
for(int i=1;(ptr=ptr->next)!=NULL;i++)
{
if(i%5)
printf("%d ", ptr->Data.data);
else
printf("%d\n", ptr->Data.data);
}
putchar(10);
return;
}
//头插法
void head_insert(dll* ptr,newtype data)
{
//创建节点
dll* temp = create_dublink_node();
temp->Data.data = data;
//头插
if(ptr->next)
{
ptr->next->prev = temp;
temp->next = ptr->next;
}
temp->prev = ptr;
ptr->next = temp;
ptr->Data.len++;
return;
}
//尾插法
void tail_insert(dll* ptr, newtype data)
{
//创建节点
dll* temp = create_dublink_node();
temp->Data.data = data;
//找到尾节点
dll* p = ptr;
while(p->next!=NULL) //判断是否到达尾节点
{
p = p->next;
}
//插入节点
temp->prev = p;
p->next = temp;
ptr->Data.len++;
return;
}
//按位置插入
int index_insert(dll* ptr, newtype data, int index)
{
if(index<1)
{
printf("位置输入不合法!\n");
return -1;
}
else
{
//创建节点
dll* temp = create_dublink_node();
temp->Data.data = data;
//查找位置
dll* p = ptr;
for(int i=1; i<index && (p=p->next)->next!=NULL; i++);
//插入数据
if(p->next==NULL)
{
temp->prev = p;
p->next = temp;
ptr->Data.len++;
return 0;
}
else
{
temp->next = p->next;
p->next = temp;
temp->prev = p;
temp->next->prev = temp;
ptr->Data.len++;
return 0;
}
}
}
//头删法
int head_del(dll* ptr)
{
//判断链表是否为空
if(ptr->next!=NULL)
{
//不为空删除第一个节点
dll* 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(dll* ptr)
{
//判断链表是否为空
if(ptr->next!=NULL)
{
//不为空删除最后一个结点
ptr->Data.len--; //链表长度减一
//找到最后一个结点
dll* p = ptr;
while(p->next->next!=NULL)
p = p->next;
//删除为结点
free(p->next);
p->next = NULL;
return 0;
}
else
{
printf("链表为空,无法删除\n");
return -1;
}
}
//按位置删除
int index_del(dll* ptr, int index)
{
//判断链表是否为空
if(ptr->next==NULL)
{
printf("链表为空,删除失败\n");
return -1;
}
//查找位置结点
int i;
dll* p = ptr->next;
for(i=1; i<index && p->next!=NULL; i++)
{
p = p->next;
}
//判断删除位置是否大于链表长度
//大于则删除最后一个结点
if(p->next==NULL)
{
if(i<index)
printf("删除位置超过链表长度,删除最后一个\n");
p->prev->next = NULL;
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;
}
}
//清空链表
dll* clear_link(dll* ptr)
{
while(ptr->next!=NULL)
{
head_del(ptr);
}
return ptr;
}
//释放链表
void free_link(dll** head)
{
clear_link(*head);
free(*head);
*head = NULL;
return;
}