双向循环链表


/*******线性表*********
 * 线性表是最基本、最简单、也是最常用的一种数据结构。
 * 线性表(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;  
    
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值