忙了许久~才弄好插入尾部节点~还有很多功能没有完善~(有些函数还没有测试~可能有bug)~嘿嘿~不过这个可以当作栈和队列通用的双向链表了~~~
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#ifndef _STRUCTURE_LIST_
#define _STRUCTURE_LIST_
#define LEN_ListNode sizeof(ListNode)
#define LEN_List sizeof(List)
typedef struct ListNode
{
void* Element; //目录
struct ListNode* next; //双向链表
struct ListNode* prior;
}ListNode,*PListNode;
typedef struct List //链表信息
{
PListNode front;
PListNode rear;
size_t size; //统计容量
int length; //统计链表长度
int Add; //存放结构体成员的地址
}List,*PList;
void Creat_Link(PList* p,void* Add,size_t size); //初始化一个链表
void Creat_Node(PListNode* p,void* Value,size_t size); //创建一个节点
int Insert_Node(PListNode p1,PListNode p2); //插入一个头节点
int Insert_Rear(PList p1,void* p2); //尾插
int Insert_Front(PList p1,void* p2); //头插
PListNode Find_Front(PList p,void* member,int k,void* Temp,int (*COM)(const void* p1,const void* p2)); //查找信息并返回该节点
PListNode Find_Node(PList p,PListNode pt,void* member,int k,void* Temp,int (*COM)(const void* p1,const void* p2)); //在当前节点开始查找
void Print_Node(void* p,void (*COM)(void* p)); //输出节点
int Print_List(PList p,void (*COM)(void* p)); //输出链表(不带换行符)
int Println_List(PList p,void (*COM)(void* p)); //输出链表(带换行符)
int RePrint_List(PList p,void (*COM)(void* p)); //逆向输出链表(不带换行符)
int RePrintln_List(PList p,void (*COM)(void* p)); //逆向输出链表(带换行符)
int Del_Node(PListNode* p); //删除一个节点
int Del_Node_ReNext(PList p,PListNode* pt); //删除一个节点并返回后一个节点
int Del_Node_RePrior(PList p,PListNode* pt); //删除一个节点并返回前一个节点
int Del_ListLink(PList* p); //删除头节点和尾节点
int Del_List(PList* p,int k); //清空链表(k=0则表示保留头尾节点,k=1则表示不保留头尾节点)
int Del_Rear(PList p,void* Value); //删除尾部数据并读取(NULL表示不读取数据)
int Del_Front(PList p,void* Value); //删除头部数据并读取(NULL表示不读取数据)
int Remove_Rear(PList p,void* Value); //读取尾部数据并删除
int Remove_Front(PList p,void* Value); //读取头部数据并删除
void* Get_Data(void* p1,void* p2,size_t size); //读取节点数据
void* Get_Data_By_Rear(PList p,void* Value); //在链表中读取尾节点数据
void* Get_Data_By_Front(PList p,void* Value); //在链表中读取头节点数据
void Reverse(PList p); //链表逆转
void Link_Sort_Auto(PList p,void* member,size_t size,int(*COM)(const void* p1,const void* p2)); //链表排序(自动快排)
void Link_Sort_NonAuto(PList p,int(*COM)(const void* p1,const void* p2)); //手动排序(自己写自定义函数)
int Copy_List(PList p1,PList p2); //复制一个链表(如果另外一个链表为非空则把数据添加至末尾)
int Empty_List(PList p); //判断链表是否为空
int Comp_Int(const void* a,const void* b); //比较INT型数据
int Comp_Float(const void* a,const void* b); //比较Float型数据
int Comp_Double(const void* a,const void* b); //比较Doulbe型数据
int Comp_Char(const void* a,const void* b); //比较Char型数据
int Comp_String(const void* a,const void* b); //比较字符串类数据
typedef struct List_FUN
{
void (*Creat_Link)(PList* p,void* Add,size_t size); //初始化一个链表
void (*Creat_Node)(PListNode* p,void* Value,size_t size); //创建一个节点
int (*Insert_Node)(PListNode p1,PListNode p2); //插入一个节点
int (*Insert_Rear)(PList p1,void* p2); //尾插
int (*Insert_Front)(PList p1,void* p2); //头插
PListNode (*Find_Front)(PList p,void* member,int k,void* Temp,int (*COM)(const void* p1,const void* p2)); //查找信息并返回该节点
PListNode (*Find_Node)(PList p,PListNode pt,void* member,int k,void* Temp,int (*COM)(const void* p1,const void* p2));//在当前节点开始查找
void (*Print_Node)(void* p,void (*COM)(void* p)); //输出节点
int (*Print_List)(PList p,void (*COM)(void* p)); //输出链表(不带换行符)
int (*Println_List)(PList p,void (*COM)(void* p)); //输出链表(带换行符)
int (*RePrint_List)(PList p,void (*COM)(void* p)); //逆向输出链表(不带换行符)
int (*RePrintln_List)(PList p,void (*COM)(void* p)); //逆向输出链表(带换行符)
int (*Del_Rear)(PList p,void* Value); //删除尾部数据并读取(NULL表示不读取数据)
int (*Del_Front)(PList p,void* Value); //删除头部数据并读取(NULL表示不读取数据)
int (*Del_NodeReNext)(PList p,PListNode* pt); //删除一个节点并返回后一个节点
int (*Del_Node_RePrior)(PList p,PListNode* pt); //删除一个节点并返回前一个节点
int (*Remove_Rear)(PList p,void* Value); //读取尾部数据并删除
int (*Remove_Front)(PList p,void* Value); //读取头部数据并删除
int (*Del_List)(PList* p,int k); //清空链表(k=0则表示保留头尾节点,k=1则表示不保留头尾节点)
void* (*Get_Data)(void* p1,void* p2,size_t size); //读取节点数据
void* (*Get_Data_By_Rear)(PList p,void* Value); //在链表中读取尾节点数据
void* (*Get_Data_By_Front)(PList p,void* Value); //在链表中读取头节点数据
void (*Reverse)(PList p); //链表逆转
void (*Link_Sort_Auto)(PList p,void* member,size_t size,int (*COM)(const void* p1,const void* p2)); //链表排序(自动快排)
void (*Link_Sort_NonAuto)(PList p,int(*COM)(const void* p1,const void* p2)); //手动排序(自己写自定义函数)
int (*Copy_List)(PList p1,PList p2); //复制一个链表(如果另外一个链表为非空则把数据添加至末尾)
int (*Empty_List)(PList p); //判断链表是否为空
int (*Comp_Int)(const void* a,const void* b); //比较INT型数据
int (*Comp_Float)(const void* a,const void* b); //比较Float型数据
int (*Comp_Double)(const void* a,const void* b); //比较Doulbe型数据
int (*Comp_Char)(const void* a,const void* b); //比较Char型数据
int (*Comp_String)(const void* a,const void* b); //比较字符串类数据
}List_Function;
List_Function List_Fun=
{
Creat_Link,
Creat_Node,
Insert_Node,
Insert_Rear,
Insert_Front,
Find_Front,
Find_Node,
Print_Node,
Print_List,
Println_List,
RePrint_List,
RePrintln_List,
Del_Rear,
Del_Front,
Del_Node_ReNext,
Del_Node_RePrior,
Remove_Rear,
Remove_Front,
Del_List,
Get_Data,
Get_Data_By_Rear,
Get_Data_By_Front,
Reverse,
Link_Sort_Auto,
Link_Sort_NonAuto,
Copy_List,
Empty_List,
Comp_Int,
Comp_Float,
Comp_Double,
Comp_Char,
Comp_String,
};
void Creat_Link(PList* p,void* Add,size_t size)
{
assert(*p=(PList)malloc(LEN_List));
memset(*p,0,LEN_List);
(*p)->Add=(int)Add; //初始化链表地址值
(*p)->size=size; //初始化链表容量
assert((*p)->front=(*p)->rear=(PListNode)malloc(LEN_ListNode));
memset((*p)->front,0,LEN_ListNode);
assert((*p)->front->next=(*p)->rear=(*p)->rear->next=(PListNode)malloc(LEN_ListNode));
memset((*p)->rear,0,LEN_ListNode);
(*p)->rear->prior=(*p)->front;
}
void Creat_Node(PListNode* p,void* Value,size_t size) //创建一个节点和和目录分配空间
{
assert((*p)=(PListNode)malloc(LEN_ListNode));
memset(*p,0,LEN_ListNode);
assert((*p)->Element=malloc(size));
memset((*p)->Element,0,size);
if (Value!=NULL)
memmove((*p)->Element,Value,size);
}
int Insert_Node(PListNode p1,PListNode p2)
{
if (p1==NULL)
return 0; //插入失败则返回0
p2->next=p1->next;
p2->prior=p1;
p1->next=p2;
if (p2->next)
p2->next->prior=p2;
return 1; //插入成果返回1
}
int Insert_Rear(PList p1,void* p2) //尾插
{
PListNode t=NULL;
if (p1==NULL)
return 0;
Creat_Node(&t,p2,p1->size);
if (Insert_Node(p1->rear->prior,t))
{
++p1->length;
return 1;
}
Del_Node(&t);
return 0;
}
int Insert_Front(PList p1,void* p2) //头插
{
PListNode t=NULL;
if (p1==NULL)
return 0;
Creat_Node(&t,p2,p1->size);
if (Insert_Node(p1->front,t))
{
++p1->length;
return 1;
}
Del_Node(&t);
return 0;
}
void Print_Node(void* p,void (*COM)(void* p)) //输出节点
{
if (p==NULL)
return ;
(*COM)(p);
}
int Print_List(PList p,void (*COM)(void* p)) //输出链表
{
PListNode t=NULL;
if (p==NULL)
return -1;
if (p->front==NULL||p->rear==NULL)
return 0;
t=p->front->next;
while (t!=p->rear)
{
Print_Node(t->Element,COM);
t=t->next;
}
return 1;
}
int Println_List(PList p,void (*COM)(void* p)) //输出链表
{
int k=Print_List(p,COM);
puts("");
return k;
}
int RePrint_List(PList p,void (*COM)(void* p))
{
PListNode t=NULL;
if (p==NULL)
return -1;
if (p->front==NULL||p->rear==NULL)
return 0;
t=p->rear->prior;
while (t!=p->front)
{
Print_Node(t->Element,COM);
t=t->prior;
}
return 1;
}
int RePrintln_List(PList p,void (*COM)(void* p)) //逆向输出链表(带换行符)
{
int k=RePrint_List(p,COM);
puts("");
return k;
}
void* Get_Data(void* p1,void* p2,size_t size) //读取节点数据
{
if (p2==NULL)
return NULL;
if (p1!=NULL)
memmove(p1,p2,size);
return p2;
}
int Del_Node(PListNode* p) //删除一个节点
{
if (*p==NULL)
return -1;
if ((*p)->Element==NULL)
return 0;
free((*p)->Element);
(*p)->Element=NULL;
free(*p);
*p=NULL;
return 1;
}
int Del_Node_ReNext(PList p,PListNode* pt) //删除一个节点并返回后一个节点
{
PListNode t=NULL;
if (p==NULL||p->length==0)
return 0;
t=(*pt)->next;
(*pt)->prior->next=(*pt)->next;
(*pt)->next->prior=(*pt)->prior;
if (Del_Node(pt))
{
--p->length;
*pt=t;
}
return 1;
}
int Del_Node_RePrior(PList p,PListNode* pt) //删除一个节点并返回前一个节点
{
PListNode t=NULL;
if (p==NULL||p->length==0)
return 0;
t=(*pt)->prior;
(*pt)->prior->next=(*pt)->next;
(*pt)->next->prior=(*pt)->prior;
if (Del_Node(pt))
{
--p->length;
*pt=t;
}
return 1;
}
int Del_ListLink(PList* p) //删除头节点和尾节点
{
if (*p==NULL)
return 0;
if ((*p)->front)
{
free((*p)->front);
(*p)->front=NULL;
}
else
return 0;
if ((*p)->rear)
{
free((*p)->rear);
(*p)->rear=NULL;
}
else
return 0;
free(*p);
*p=NULL;
return 1;
}
int Del_Rear(PList p,void* Value) //删除尾部数据
{
PListNode t=NULL;
if (p==NULL||p->length==0)
return 0;
t=p->rear->prior;
t->prior->next=t->next;
t->next->prior=t->prior;
if (Del_Node(&t))
--p->length;
if (Value==NULL)
return 1;
if (p->rear->prior->Element!=NULL)
Get_Data(Value,p->rear->prior->Element,p->size);
return 1;
}
int Del_Front(PList p,void* Value) //删除头部数据
{
PListNode t=NULL;
if (p==NULL||p->length==0)
return 0;
t=p->front->next;
t->prior->next=t->next;
t->next->prior=t->prior;
if (Del_Node(&t))
--p->length;
if (Value==NULL)
return 1;
if (p->front->next->Element!=NULL)
Get_Data(Value,p->front->next->Element,p->size);
return 1;
}
int Remove_Rear(PList p,void* Value) //读取尾部数据并删除
{
if (p==NULL||p->length==0)
return 0;
if (Value!=NULL)
memmove(Value,p->rear->prior->Element,p->size);
return Del_Rear(p,NULL);
}
int Remove_Front(PList p,void* Value) //读取头部数据并删除
{
if (p==NULL||p->length==0)
return 0;
if (Value!=NULL)
memmove(Value,p->front->next->Element,p->size);
return Del_Front(p,NULL);
}
int Del_List(PList* p,int k) //清空链表(k=0则表示保留头尾节点,k=1则表示不保留头尾节点)
{
if (k==0&&Del_Front(*p,NULL)==0)
return 0;
while (Del_Front(*p,NULL));
if (k)
return Del_ListLink(p);
return 1;
}
PListNode Find_Node(PList p,PListNode pt,void* member,int k,void* Temp,int (*COM)(const void* p1,const void* p2)) //在当前节点开始查找
{
PListNode t=pt;
if (t==NULL)
return NULL;
while (t->next!=NULL)
{
if (t->Element!=NULL&&(*COM)((const void* )((int)(t->Element)+((int)member-p->Add)),(const void*)member)==k)
break;
t=t->next;
}
if (t->Element!=NULL&&Temp!=NULL)
{
Get_Data(Temp,t->Element,p->size);
return t;
}
else if (t->next!=NULL)
return t;
return NULL;
}
PListNode Find_Front(PList p,void* member,int k,void* Temp,int (*COM)(const void* p1,const void* p2)) //查找信息并返回该节点
{
if (p==NULL||p->front->next==p->rear)
return NULL;
return Find_Node(p,p->front->next,member,k,Temp,COM);
}
void* Get_Data_By_Rear(PList p,void* Value) //获取表尾数据
{
if (p==NULL||p->front->next==p->rear)
return NULL;
return Get_Data(Value,p->rear->prior->Element,p->size);
}
void* Get_Data_By_Front(PList p,void* Value) //获取表头数据
{
if (p==NULL||p->front->next==p->rear)
return 0;
return Get_Data(Value,p->front->next->Element,p->size);
}
void Reverse(PList p) //链表逆转
{
PListNode p1=NULL;
PListNode p2=NULL;
PListNode pt=NULL;
if (p==NULL)
return ;
p1=p->front;
p2=p1;
pt=p1;
if (p->length==0)
return ;
while (p2=p2->next)
{
p1->next=p1->prior;
p1=p1->prior=p2;
}
p1->next=p1->prior;
p1->prior=NULL;
p->front=p1;
p->rear=pt;
}
int Empty_List(PList p) //判断链表是否为空
{
if (p==NULL)
return 0;
return p->length==0;
}
void Link_Sort_Auto(PList p,void* member,size_t size,int (*COM)(const void* p1,const void* p2)) //自动快排
{
size_t T_size=p->size*(p->length);
int length=p->length;
char* Temp=(char* )malloc(T_size); //创建排序缓冲区
char* PTemp=Temp;
int i=0;
size_t size1=(int )member-p->Add;
size_t size2=size;
size_t size3=p->size-size1-size2;
assert(Temp);
memset(Temp,0,T_size);
while (p->length!=0) //拷贝数据到缓冲区
{
memmove(PTemp,(void* )((int )p->front->next->Element+size1),size2);
PTemp+=size2;
memmove(PTemp,(void* )((int )p->front->next->Element),size1);
PTemp+=size1;
memmove(PTemp,(void* )((int )p->front->next->Element+size1+size2),size3);
PTemp+=size3;
Del_Front(p,PTemp);
}
qsort(Temp,length,p->size,COM); //快排
for (i=0,PTemp=Temp;i!=length;++i) //把快排后的数据写回链表
{
Insert_Rear(p,NULL);
memmove(p->rear->prior->Element,PTemp+size2,size1);
memmove((void* )((int )p->rear->prior->Element+size1),PTemp,size2);
memmove((void* )((int )p->rear->prior->Element+size1+size2),PTemp+size1+size2,size3);
PTemp+=p->size;
}
PTemp=NULL;
free(Temp);
Temp=NULL;
}
void Link_Sort_NonAuto(PList p,int(*COM)(const void* p1,const void* p2)) //手动排序(自己写自定义函数)
{
size_t T_size=p->size*(p->length);
int length=p->length;
char* Temp=(char* )malloc(T_size); //创建排序缓冲区
char* PTemp=Temp;
int i=0;
assert(Temp!=NULL);
memset(Temp,0,T_size);
Get_Data_By_Front(p,PTemp);
while (p->length!=0)
Del_Front(p,PTemp+=p->size);
qsort(Temp,length,p->size,COM);
for (i=0,PTemp=Temp;i!=length;++i) //把快排后的数据写回链表
{
Insert_Rear(p,PTemp);
PTemp+=p->size;
}
PTemp=NULL;
free(Temp);
Temp=NULL;
}
int Copy_List(PList p1,PList p2)
{
PListNode pt=NULL;
int i=p2->length;
if (p1==NULL||p2==NULL)
return 0;
pt=p2->front->next;
while (i--)
{
Insert_Rear(p1,pt->Element);
pt=pt->next;
}
return 1;
}
int Comp_Int(const void* a,const void* b) //比较INT型数据
{
int ta=*(int* )a;
int tb=*(int* )b;
if (ta<tb)
return -1;
if (ta>tb)
return 1;
return 0;
}
int Comp_Float(const void* a,const void* b) //比较Float型数据
{
float ta=*(float* )a;
float tb=*(float* )b;
if (ta<tb)
return -1;
if (ta>tb)
return 1;
return 0;
}
int Comp_Double(const void* a,const void* b) //比较Doulbe型数据
{
double ta=*(double* )a;
double tb=*(double* )b;
if (ta<tb)
return -1;
if (ta>tb)
return 1;
return 0;
}
int Comp_Char(const void* a,const void* b) //比较Char型数据
{
char ta=*(char* )a;
char tb=*(char* )b;
if (ta<tb)
return -1;
if (ta>tb)
return 1;
return 0;
}
int Comp_String(const void* a,const void* b) //比较字符串类数据
{
int t=strcmp((char* )a,(char* )b);
if (t<0)
return -1;
if (t>0)
return 1;
return 0;
}
#endif
程序代码:
#include"List.h"
#include<time.h>
typedef struct Node
{
int a;
char b;
double c;
}Node,*PNode;
Node node={0};
Node t_node={0};
void Print_COM(void* p);
int COM(const void* pa,const void* pb);
int main()
{
PList p=NULL;
PList p2=NULL;
PListNode pp=NULL;
PNode pn=NULL;
int i=0;
srand((unsigned )time(NULL));
List_Fun.Creat_Link(&p,&node,sizeof(Node));
puts("尾插");
for (i=0;i<5;++i)
{
node.a=rand()%100;
node.b=rand()%26+'a';
node.c=rand()/16383.0;
List_Fun.Insert_Rear(p,&node); //尾插
}
List_Fun.Println_List(p,Print_COM); //输出链表
puts("逆序输出");
List_Fun.RePrintln_List(p,Print_COM); //逆序输出
puts("头插");
for (i=5;i<10;++i)
{
node.a=i;
node.b='a'+i;
node.c=rand()/16383.0;
List_Fun.Insert_Front(p,&node); //头插
}
List_Fun.Println_List(p,Print_COM);
puts("逆序输出");
List_Fun.RePrintln_List(p,Print_COM);
puts("尾删");
List_Fun.Del_Rear(p,NULL); //尾删
List_Fun.Del_Rear(p,NULL);
List_Fun.Println_List(p,Print_COM);
puts("头删");
List_Fun.Del_Front(p,NULL); //头删
List_Fun.Del_Front(p,NULL);
List_Fun.Println_List(p,Print_COM);
node.a=5;
printf("从头节点开始查找元素%d\n",node.a);
pp=List_Fun.Find_Front(p,&node.a,0,&t_node,List_); //从头节点开始查找
if (pp!=NULL)
{
printf("%d %c %.2f\n",((PNode)pp->Element)->a,((PNode)pp->Element)->b,((PNode)pp->Element)->c);
printf("%d %c %.2f\n\n",t_node.a,t_node.b,t_node.c);
}
pp=p->front->next->next;
node.b='g';
printf("从头节点开始查找元素%c\n",node.b);
pp=List_Fun.Find_Front(p,&node.b,0,&t_node,List_);
if (pp!=NULL)
{
printf("%d %c %.2f\n",((PNode)pp->Element)->a,((PNode)pp->Element)->b,((PNode)pp->Element)->c);
printf("%d %c %.2f\n\n",t_node.a,t_node.b,t_node.c);
}
node.a=5;
printf("从当前节点开始查找元素%d\n",node.a);
pp=List_Fun.Find_Node(p,pp,&node.a,1,&t_node,List_); //从指定节点开始查找
if (pp!=NULL)
{
printf("%d %c %.2f\n",((PNode)pp->Element)->a,((PNode)pp->Element)->b,((PNode)pp->Element)->c);
printf("%d %c %.2f\n\n",t_node.a,t_node.b,t_node.c);
}
puts("手动快排");
List_Fun.Link_Sort_NonAuto(p,COM); //手动快排
List_Fun.Println_List(p,Print_COM);
puts("链表逆转");
List_Fun.Reverse(p); //链表逆转
List_Fun.Println_List(p,Print_COM);
puts("自动快排");
Link_Sort_Auto(p,&node.b,sizeof(node.b),List_); //自动快排
List_Fun.Println_List(p,Print_COM);
puts("自动快排");
Link_Sort_Auto(p,&node.c,sizeof(node.c),List_); //自动快排
List_Fun.Println_List(p,Print_COM);
printf("链表长度为%d\n",p->length);
puts("复制链表"); //复制链表
List_Fun.Creat_Link(&p2,&node,sizeof(Node));
List_Fun.Copy_List(p2,p);
List_Fun.Println_List(p2,Print_COM);
List_Fun.Del_List(&p,1); //释放链表
List_Fun.Del_List(&p2,1);
return 0;
}
void Print_COM(void* p)
{
PNode t=(PNode)p;
printf("%-4d",t->a);
printf("%-4c",t->b);
printf("%-.2f",t->c);
puts("");
}
int COM(const void* pa,const void* pb)
{
int a=((PNode)pa)->a;
int b=((PNode)pb)->a;
if (a>b)
return 1;
if (a<b)
return -1;
return 0;
}
[此贴子已经被作者于2017-6-4 21:38编辑过]