已修正bug~~链表快排欢迎公测~
为了不误导大家~原帖手动快排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(PListNode* p); //删除一个节点并返回后一个节点 int Del_Node_RePrior(PListNode* p); //删除一个节点并返回前一个节点 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 Get_Data(void* p1,void* p2,size_t size); //读取节点数据 int Get_Data_By_Rear(PList p,void* Value); //在链表中读取尾节点数据 int 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 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)(PListNode* p); //删除一个节点并返回后一个节点 int (*Del_Node_RePrior)(PListNode* p); //删除一个节点并返回前一个节点 int (*Del_List)(PList p,int k); //清空链表(k=0则表示保留头尾节点,k=1则表示不保留头尾节点) int (*Get_Data)(void* p1,void* p2,size_t size); //读取节点数据 int (*Get_Data_By_Rear)(PList p,void* Value); //在链表中读取尾节点数据 int (*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 (*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, Del_List, Get_Data, Get_Data_By_Rear, Get_Data_By_Front, Reverse, Link_Sort_Auto, Link_Sort_NonAuto, 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); 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||p2==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||p2==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; } int Get_Data(void* p1,void* p2,size_t size) //读取节点数据 { if (p1==NULL||p2==NULL) return 0; memmove(p1,p2,size); return 1; } 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(PListNode* p) //删除一个节点并返回后一个节点 { PListNode pt=NULL; if (*p==NULL) return -1; if ((*p)->Element==NULL) return 0; pt=(*p)->next; free((*p)->Element); (*p)->Element=NULL; free(*p); *p=pt; return 1; } int Del_Node_RePrior(PListNode* p) //删除一个节点并返回前一个节点 { PListNode pt=NULL; if (*p==NULL) return -1; if ((*p)->Element==NULL) return 0; pt=(*p)->prior; free((*p)->Element); (*p)->Element=NULL; free(*p); *p=pt; 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=p->rear->prior; if (p==NULL||t==NULL||p->front==t) return 0; 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=p->front->next; if (p==NULL||t==NULL||p->rear==t) return 0; 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 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); } int Get_Data_By_Rear(PList p,void* Value) //获取表尾数据 { if (p==NULL||p->front->next==p->rear) return 0; return Get_Data(Value,p->rear->prior->Element,p->size); } int 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=p->front; PListNode p2=p1; PListNode pt=p1; if (p->front->next==p->rear) 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; } 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; char* buff=malloc(p->size); int i=0; size_t size1=(int)member-p->Add; size_t size2=size; size_t size3=p->size-size1-size2; assert(Temp); assert(buff); memset(Temp,0,T_size); memset(buff,0,size); while (p->length!=0) //拷贝数据到缓冲区 { Get_Data_By_Front(p,buff); memcpy(PTemp,buff+size1,size2); PTemp+=size2; memcpy(PTemp,buff,size1); PTemp+=size1; memcpy(PTemp,buff+size1+size2,size3); PTemp+=size3; Del_Front(p,PTemp); } qsort(Temp,length,p->size,COM); //快排 for (i=0,PTemp=Temp;i!=length;++i) //把快排后的数据写回链表 { char* pbuff=buff; memcpy(pbuff,PTemp+size2,size1); pbuff+=size1; memcpy(pbuff,PTemp,size2); pbuff+=size2; memcpy(pbuff,PTemp+size1+size2,size3); Insert_Rear(p,buff); PTemp+=p->size; } PTemp=NULL; free(Temp); free(buff); Temp=NULL; buff=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) { PTemp+=p->size; Del_Front(p,PTemp); } 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 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; float 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; PListNode pp=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=(float)(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); } 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); List_Fun.Del_List(p,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; }
暂时没有发现bug~昨晚调试这个到520才睡觉~~本来打算发帖来看看怎么改bug的~结果一不小心被自己发现了~~
[此贴子已经被作者于2017-5-18 13:44编辑过]