/*******线性表*********
* 线性表是最基本、最简单、也是最常用的一种数据结构。
* 线性表(linear list)是数据结构的一种,
* 一个线性表是n个具有相同特性的数据元素的有限序列
* 线性表以下四个特征:
* 1.集合中必存在唯一的一个“第一元素”。
* 2.集合中必存在唯一的一个 “最后元素” 。
* 3.除最后一个元素之外,均有唯一的后继(后件)。
* 4.除第一个元素之外,均有唯一的前驱(前件)。
* ************************/
/*******双向循环链表 *********
* 描述:结点 =数据域 + 前驱指针域 + 后继指针域
* ************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DataStaruct.h"
#include "phoneNote.h"
#define MAX_SIZE 20
typedef PhoneNote elemType;
/// @brief 双向链表结点
typedef struct dulinkNode{
/// @brief 数据
elemType data;
/// @brief 前驱
struct dulinkNode *prior;
/// @brief 后继
struct dulinkNode *next;
}dulinkNode;
/// @brief 双向循环链表
typedef struct loopdulinkList
{
/// @brief 头结点
dulinkNode *frist;
/// @brief 尾结点
dulinkNode *last;
/// @brief 数量
int size;
}loopdulinkList;
#define m_data "list.data"
#define BUFF_SZIE 100
#define CAPTION "loopdulinkList"
#define m_print(list) showloopdulinkList(list,phoneNote_printw)
#define m_load(list) loadloopdulinkList(list,m_data,phoneNote_creat)
#define m_save(list) saveloopdulinkList(list,m_data)
#define m_search(list,key,value,del) searchloopdulinkList(list,key,value,phoneNote_search,del)
#define m_insert(list,item,pos) insertloopdulinkList(list,item,pos)
#define m_delete(list,pos) deleteloopdulinkList(list,pos)
#define m_clear(list) clearloopdulinkList(list)
#define m_destroy(list) destroyloopdulinkList(list)
#define m_lenght(list) getLenghtloopdulinkList(list)
#define m_modify(list,pos) modifyloopdulinkList(list,pos,phoneNote_modify)
#define m_merge(la,lb) mergeloopdulinkList(la,lb)
#define m_sort(list,key,desc) sortloopdulinkList(list,key,phoneNote_cmp,desc)
#define m_resver(list) resverloopdulinkList(list)
#define m_inputelem() phoneNote_scanf()
loopdulinkList* createloopdulinkList()
{
dulinkNode* elem=(dulinkNode*)calloc(1,sizeof(dulinkNode));
if(!elem)return NULL;
loopdulinkList* result= (loopdulinkList*)calloc(1,sizeof(loopdulinkList));
if(!result)return NULL;
result->frist=result->last=elem;
result->frist->prior=result->last;
result->last->next=result->frist;
result->size=0;
return result;
}
int getLenghtloopdulinkList(loopdulinkList* list){return list->size;}
int insertloopdulinkList(loopdulinkList* list, elemType *item, int pos)
{
int j=0;
dulinkNode* cursor=list->frist;
dulinkNode* newElem=NULL;
if(!cursor || !item)return -1;
while(cursor && j<pos && cursor->next!=list->frist)
{cursor=cursor->next,j++;}
if(!cursor || j>pos) return -2;
if(!(newElem=(dulinkNode*)calloc(1,sizeof(dulinkNode))))return -3;
memcpy(&(newElem->data),item,sizeof(elemType));
newElem->next=cursor->next;
cursor->next=newElem;
newElem->prior=cursor;
if(newElem->next!=NULL)
newElem->next->prior=newElem;
list->size++;
return 0;
}
int deleteloopdulinkList(loopdulinkList* list, int pos)
{
int j=0;
dulinkNode* cursor=list->frist;
dulinkNode* tmp=NULL;
while(cursor->next && j<pos){cursor=cursor->next;j++;}
if(!cursor || j>pos)return -1;
tmp=cursor->next;
if(cursor->next->next)
{cursor->next=cursor->next->next;
cursor->next->prior=cursor;
}
else{cursor->next=NULL;}
free(tmp);
list->size--;
return 0;
}
int modifyloopdulinkList(loopdulinkList* list, int pos, int (*elemModify)(elemType *p))
{ int j=0;
dulinkNode* cursor=list->frist;
//dulinkNode* newList=NULL;
while(cursor->next && j<pos+1 && cursor->next!=list->frist)
{cursor=cursor->next;j++;}
if(!cursor || j>pos+1)return -1;
return elemModify(&(cursor->data));
}
loopdulinkList* searchloopdulinkList(loopdulinkList* list, const char *key, const char *value, elemType *(*elemSearch)(elemType *p, const char *key, const char *value), int del)
{
int j=0;
loopdulinkList* rel=createloopdulinkList();
dulinkNode* cursor=list->frist;
while( cursor &&(cursor=cursor->next)!=list->frist && cursor!=NULL)
{
if(elemSearch(&(cursor->data),key,value))
{
insertloopdulinkList(rel,&(cursor->data),getLenghtloopdulinkList(rel));
if(del==1){deleteloopdulinkList(list,j);cursor=list->frist;j=0;continue;}
}
j++;
}
return rel;
}
int showloopdulinkList(loopdulinkList* list, void (*_print)(elemType *p))
{ dulinkNode* cursor=list->frist;
if(cursor==NULL || _print==NULL) return -1;
printf("\n--------- Show list ------------------\n");
while((cursor=cursor->next)!=list->frist)
{_print(&(cursor->data));/*cursor=cursor->next;*/}
printf("----------- Total: %d -------------------\n\n",getLenghtloopdulinkList(list));
return 0;
}
int clearloopdulinkList(loopdulinkList* list)
{
dulinkNode* cursor=list->frist;
dulinkNode* tmp=NULL;
int j=0;
while(cursor && cursor !=list->frist)
{
tmp=cursor->next;
cursor=cursor->next->next ;
free(tmp);
j++;
}
list->frist->next=list->frist->prior=list->frist;
list->last=list->frist;
list->size=0;
return 0;
}
int destroyloopdulinkList(loopdulinkList **list)
{
clearloopdulinkList((*list));
free((*list)->frist);
free(*list);
*list=NULL;
return 0;
}
int loadloopdulinkList(loopdulinkList* list, const char *file, elemType *(*_creatItem)())
{
FILE* fp = fopen(file, "r");
elemType* item=NULL;
if(list==NULL)
{ printf("sequence list is null\n");
return -1;}
if(fp==NULL){
printf("Failed to open file\n");
return -2;
}
item=_creatItem();
if(item==NULL){
printf("Failed to Create empty elemType\n");
return -3;}
clearloopdulinkList(list);
while(fread(item,sizeof(elemType),1,fp))
{
if(insertloopdulinkList(list,item,getLenghtloopdulinkList(list)))break;
}
fclose(fp);
}
int saveloopdulinkList(loopdulinkList* list, const char *file)
{
dulinkNode* cursor=list->frist;
FILE* fp = fopen(file, "w");
if(cursor==NULL) {printf("sequence list is null\n");return -1;}
if(fp==NULL){ printf("Failed to open file\n"); return -2; }
while((cursor=cursor->next)!=list->frist && cursor)
{
fwrite(&(cursor->data),sizeof(elemType),1,fp);
}
fclose(fp);
return 0;
}
loopdulinkList* mergeloopdulinkList(loopdulinkList* la,loopdulinkList* lb)
{
dulinkNode* cursor=NULL;
loopdulinkList* rel=createloopdulinkList();
loopdulinkList* array[]={la,lb};
for (size_t i = 0; i < 2; i++)
{
cursor=array[i]->frist;
while((cursor=cursor->next)!=array[i]->frist && cursor->next)
{
insertloopdulinkList(rel,&(cursor->data),getLenghtloopdulinkList(rel));
}
}
return rel;
}
int sortloopdulinkList(loopdulinkList* list, const char* key, int (*elemCmp)(elemType *p1,elemType* p2, const char* key),int desc)
{
/*** 插入排序
* 1.从第一个元素开始,该元素可以认为已经被排序;
* 2.取出下一个元素,在已经排序的元素序列中从后向前扫描;
* 3.如果该元素(已排序)大于新元素,将该元素移到下一位置;
* 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
* 5.将新元素插入到该位置后;
* 6.重复步骤2~5。
* 算法的时间复杂度为O(n^2)
* ***/
if(!list && list->frist->next!=NULL &&list->frist->next->next!=NULL) return 0;
dulinkNode* s=list->frist->next;
dulinkNode* q=s->next;
dulinkNode* p=NULL;
list->frist->next->next=list->frist;
while(q!=list->frist)
{
s=q;
q=q->next;
p=list->frist;
switch (desc)
{
case 0:
while(p->next!=list->frist && elemCmp(&(p->next->data),&(s->data),key)<=0){p=p->next;}
break;
case 1:
while(p->next!=list->frist && elemCmp(&(p->next->data),&(s->data),key)>0){p=p->next;}
break;
default:
while(p->next!=list->frist && elemCmp(&(p->next->data),&(s->data),key)<=0){p=p->next;}
break;
}
// while(p->next && elemCmp(&(p->next->data),&(s->data),key)<=0){p=p->next;}
// while(p->next && elemCmp(&(p->next->data),&(s->data),key)>0){p=p->next;}
s->next=p->next;p->next=s;
s->prior=p;
if(s->next)s->next->prior=s;
}
return 0;
}
int resverloopdulinkList(loopdulinkList* list)
{
if(!list->frist && !list->frist->next &&!list->frist->next->next) return 0;
dulinkNode *s=0,*q=0;
s=list->frist->next;
q=s->next;
list->frist->next->next=list->frist;
while(q!=list->frist)
{
s=q;q=q->next;
s->next=list->frist->next;list->frist->next=s;
s->prior=list->frist;
if(s->next)s->next->prior=s;
}
return 0;
}
int loopdulinkListTest(int argc, char const **argv)
//int main(int argc, char const **argv)
{
loopdulinkList* list=NULL;
loopdulinkList* newlist=NULL;
int pos=0,rel=0,errorCode=0;
elemType *item =NULL;
int select = 1;
char a=0x00;
list=createloopdulinkList();
while (select)
{
char cmd[100]={0};
char key[100]={0};
char value[100]={0};
printf("\n******\t%s\t******************\n",CAPTION);
printf("* [1] insert_pos [2] delete_pos *\n");
printf("* [3] show_list [4] search *\n");
printf("* [5] sort [6] resver *\n");
printf("* [7] clear [8] merge *\n");
printf("* [9] reduce [10] delete_val *\n");
printf("* [11] load [12] save *\n");
printf("* [13] modify *\n");
printf("* [0] quit *\n");
printf("************************************\n");
printf("\e[1;32mplease Enter :>\e[0m");
scanf("%d", &select);
switch (select)
{
case 0:
printf("\e[1;31m %s goodbye!\n\e[0m",CAPTION);
m_destroy(&list);
return 0;/*exit(0);*/
break;
case 1://insert_pos
pos=m_lenght(list);
printf("Please enter the insertion position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if((cmd[0]>=0x30 && cmd[0]<=0x39)||cmd[0]==0x2d )
{pos=atoi(cmd);
if(pos<0 || pos>getLenghtloopdulinkList(list))
{printf("Insert position out of bounds\n");break;}
}
if((item=m_inputelem())==NULL)
{ printf("insert failed,Element is empty\n");break; }
if(!(errorCode=m_insert(list,item,pos))) {m_print(list);}
else
{printf("\e[1;31m %s failed. Error code[%d]\n\e[0m","Insert position out of bounds ",errorCode);}
break;
case 2://del_pos
pos=m_lenght(list)-1;
printf("Please enter the Delete position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if((cmd[0]>=0x30 && cmd[0]<=0x39)||cmd[0]==0x2d )
{pos=atoi(cmd);
if(pos<0 || pos>getLenghtloopdulinkList(list)-1)
{printf("Delete position out of bounds\n");break;}
}
if(!(errorCode=m_delete(list,pos)))
{m_print(list);}
else
{printf("\e[1;31m %s failed. Error code[%d]\n\e[0m","delete",errorCode);}
break;
case 3: //show_list
m_print(list);
break;
case 4: //search
printf("Please enter the search key ");scanf("%s",key);
printf("Please enter the search value ");scanf("%s",value);
m_print(m_search(list,key,value,0));
break;
case 5: //sort
printf("Please enter the sort key [name] ");scanf("%c",key); scanf("%[^\n]",key);
if(key[0]<0x30) strncpy(key,"name",strlen("name"));
printf("Please enter the sort key < 0 :abs ,1: desc > [0] ");scanf("%c",cmd); scanf("%[^\n]",cmd);
pos=0;if(cmd[0]>=0x30) {pos=atoi(cmd);}
m_sort(list,key,pos);
m_print(list);
break;
case 6: //resver
m_resver(list);
m_print(list);
break;
case 7: //clear
m_clear(list);
m_print(list);
break;
case 8: //merge
newlist=createloopdulinkList();
m_load(newlist) ;
m_print(m_merge(list,newlist));
break;
case 9: //reduce
printf("\033[32m Do not reduce \033[0m\n");
break;
case 10: //delete_val
printf("Please enter the delete key ");scanf("%s",key);
printf("Please enter the delete value ");scanf("%s",value);
m_print(m_search(list,key,value,1));
m_print(list);
break;
case 11: //load
if(!(errorCode=m_load(list)))
m_print(list);
else {printf("\e[1;31m %s failed. Error code[%d]\n\e[0m","load",errorCode);}
break;
case 12: //save
if(!(errorCode=m_save(list)))
printf("\e[1;31m save successful \n\e[0m");
break;
case 13: //modify
pos=m_lenght(list)-1;
printf("Please enter the insertion position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if(cmd[0]>=0x30 && cmd[0]<=0x39 ) {pos=atoi(cmd);}
m_modify(list,pos);
m_print(list);
break;
default: //please re-enter
printf("\033[32m Wrong selection, please re-enter \033[0m\n");
break;
}
printf("press any key to continue...... ");
/*************************
* scanf()中的%c 不能正常输入的问题
* 在*%c前面加一个空格,将存于缓冲区中的回车符读入
* char a;
* scanf("%c%c",&a,&a);
*************************/
scanf("%c%c",&a,&a);
}
return 0;
}
双向循环链表
最新推荐文章于 2024-07-24 13:48:01 发布