线性顺序表

/*******线性表*********
 * 线性表是最基本、最简单、也是最常用的一种数据结构。
 * 线性表(linear list)是数据结构的一种,
 * 一个线性表是n个具有相同特性的数据元素的有限序列
 * 线性表以下四个特征:
 * 1.集合中必存在唯一的一个“第一元素”。
 * 2.集合中必存在唯一的一个 “最后元素” 。
 * 3.除最后一个元素之外,均有唯一的后继(后件)。
 * 4.除第一个元素之外,均有唯一的前驱(前件)。
 * ************************/

/*******线性顺序表*********

 * 1.特点:逻辑关系相邻的两个元素在物理位置上也是相邻的。
 * 优点:可以快速随机存取表中的任一元素。
 *      无需为表示表中元素之间的逻辑关系而增加额外的存储空间
 * 缺点:在作插入或删除操作时,需要移动大量的元素。
 *      当线性表长度变化较大时,难以确定存储空间的容量,造成存储空间的碎片
 * 适用:适用于需要大量访问元素的,而增加/删除元素较少的程序
 * ************************/




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "phoneNote.h"


#define m_print(list) showSeqList(list,phoneNote_printw)
#define m_search(list,key,value,del) searchSeqList(list,key,value,phoneNote_search,del)
#define m_sort(list,key) sortSeqList(list,key,phoneNote_cmp,phoneNote_swap)
#define m_resver(list) reverSeqList(list,phoneNote_swap)
#define m_modify(list,pos) modifySeqList(list,pos,phoneNote_modify)


#define m_data "seqList.data"
#define SEQLIST_INIT_SIZE 10 
#define SEQLIST_INCREMENT 3
#define CAPTION "seqList"



typedef PhoneNote elemType;
typedef void(* elemPrint)(elemType *p);
typedef elemType *(*elemSearch)(elemType *p, const char *key, const char *value);
typedef int (*elemCmp)(elemType *p1,elemType* p2, const char* key);
typedef int (*elemSwap)(elemType *p1,elemType* p2);
typedef int (*elemModify)(elemType *p);


/// @brief 线性顺序表
typedef struct seqList
{
   
      /// @brief 存储空间基地址
      elemType *base;
      /// @brief 当前存储容量
      int capacity;
      /// @brief 当前存储大小
      int size;
}seqList;     

void returnSeqList()
{
    char a;
    printf("press any key to continue......   ");
     /*************************
     * scanf()中的%c 不能正常输入的问题
     * 在*%c前面加一个空格,将存于缓冲区中的回车符读入
     * char a;
     * scanf("%c%c",&a,&a); 
     *************************/
    scanf("%c%c",&a,&a);
}
seqList * createSeqList(int size)
{
   
    seqList* rel= (seqList*)calloc(1,sizeof(seqList));    
    if(rel==NULL){return NULL;}  
    rel->base = (elemType *)calloc(size, sizeof(elemType));
    if(rel->base==NULL)  {free(rel);return NULL;}  
    rel->capacity = size;
    return rel;
}

int getLenghtSeqList(seqList* list)
{
    if(list==NULL) 
    {   
        printf("sequence list  is null\n");
        return -1;}
    printf("sequence list   Total:%d\n",list->size);
    return list->size ;
}
int incrementSeqList(seqList *list,int size)
{   elemType *newbase=NULL;
    newbase=(elemType *)realloc(list->base,(list->capacity+size)*sizeof(elemType));
    if(newbase==NULL){
        printf("Automatic capacity expansion failed\n"); return 1;
       
    }
    list->base=newbase;
    list->capacity+=size;
    printf("Automatic capacity expansion successfully\n");
    return 0;
}
int insertSeqList(seqList *list, elemType *item,int pos)
{ 
    if(list==NULL)  { printf("sequence list  is null\n");    return -1;}
   if(item==NULL)  {   printf("item  is null\n");   return -1;}
   if(list->size>=list->capacity)
 {   
    printf("The sequence list space is full\n Automatic capacity expansion\n");
    if(0!=incrementSeqList(list,SEQLIST_INCREMENT)){return 1;}  
 }
    
      if(pos>=list->size){pos=list->size;}
      if(pos<0){pos=0;}
    for (size_t i = list->size; i >pos; i--)
    {
        memcpy(list->base+i,list->base+i-1,sizeof(elemType));
        
    }    
    memcpy(list->base+pos,item,sizeof(elemType));
    list->size++;
    printf("The sequence list insert successfully\n\n");    
    return 0;
}
int showSeqList(seqList *list,elemPrint print)
{
     if(list==NULL) 
    {   printf("sequence list  is null\n");
        return -1;}
    if(print==NULL) 
    {   printf("print function  is null\n");
        return -2;}
    printf("\n-----Show sequence list ------- --------\n");
    for (size_t i = 0; i < list->size; i++)
    {  print((list->base+i));}
    printf("----------- Total: %d  --------------------\n\n",list->size);
    return 0;
}


int saveSeqList(seqList *list, const char *file)
{
    FILE* fp = fopen(file, "wb");
    if(list==NULL) 
    {   
        printf("sequence list  is null\n");
        return -1;
    }
    if(fp==NULL)
    {
        printf("Failed to open file\n");
        return -2;
    }    
    fwrite(list->base,sizeof(elemType),list->size,fp);
     fclose(fp);
     return 0;
}
int loadSeqList(seqList *list, const char *file)
{
     FILE* fp = fopen(file, "rb");
     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=phoneNote_creat();
     if(item==NULL){
        printf("Failed to Create empty elemType\n");
        return -3;}
     while(fread(item,sizeof(elemType),1,fp))
     {
        insertSeqList(list,item,list->size);
     }    
     fclose(fp);
}

elemType *deleteSeqList(seqList *list, int pos)
{  
    elemType *rel =(elemType*)calloc(1,sizeof(elemType));
    if(list==NULL){ printf("sequence list  is null\n");return NULL;}      
    if(rel==NULL){printf("elemType create  is null\n");return rel;}   
    if(pos>=list->size){pos=list->size-1;}
      if(pos<0){pos=0;}
    memcpy(rel,list->base+pos,sizeof(elemType));
    for (int i = pos; i <list->size-1; i++)
    {
       memcpy(list->base+i,list->base+i+1,sizeof(elemType));
    }
     list->size--;
     return rel;
}
seqList* searchSeqList(seqList* list,const char* key,const char* value,elemSearch msearch,int del)
{
   seqList *rel=createSeqList(SEQLIST_INIT_SIZE);       
    for (int i = 0; i < list->size; ++i)
    { if(msearch(list->base+i,key,value)!=NULL)
        {  
         insertSeqList(rel,list->base+i,rel->size);
         if(del==1){deleteSeqList(list,i); i=i-1;}
         }   
    }
    return rel;
    
}

int clearSeqList(seqList *list)
{
    list->size=0;
    return 0;
}
int destroySeqList(seqList **list)
{
    free((**list).base); 
    (**list).capacity=0;
    (**list).size=0;  
    (**list).base=NULL;
    free(*list);
    *list=NULL;
    return 0;   
}
int sortSeqList(seqList* list ,const char* key, elemCmp cmp,elemSwap swap)
{
    /* 冒泡排序 */
   /* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
    /* 2. 对所有元素均重复以上步骤,直至最后一个元素 */

     for (int i=0; i<list->size-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
        for (int j=0; j<list->size-1-i; j++) /* 内循环为每趟比较的次数,第i趟比较len-i次 */
        {   if (cmp(list->base+j,list->base+j+1,key)>0)/* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
             swap(list->base+j,list->base+j+1);
        }
    return 0;
}
int reverSeqList(seqList* list,elemSwap swap)
{
   if(list->size<1) return 0;  
  for (int i = 0; i < list->size/2 ; i++)
  {     swap(list->base+i,list->base+list->size-i-1);   }
    
 return 0;    
}
seqList* mergeSeqList(seqList *la,seqList *lb)
{ 
    if(la->size<1 || lb->size <1) return NULL;
    seqList *rel =NULL;int total=0;    
    if((rel=createSeqList(la->size+lb->size))==NULL){printf("Sequence table creation failed\n");return NULL;}
    for (int i = 0; i < la->size; i++){ insertSeqList(rel,la->base+i,rel->size); }
    for (int i = 0; i < lb->size; i++){ insertSeqList(rel,lb->base+i,rel->size); }
    return rel;
}
int modifySeqList(seqList *list, int pos, elemModify modify)
{
    if(list==NULL || list->size< 1){printf("sequence list  is null\n");return -1;}
    if(pos<0 || pos>list->size){printf("Position out of range\n"); return-2;}    
    return modify(list->base+pos);   
}
int reduceSeqList(seqList *list, int min)
{   elemType *newbase=NULL;
    
    if(list->size<1){return -1;};  
    newbase=(elemType *)calloc(list->size,sizeof(elemType));
    if(newbase==NULL){return -2;}
    for (size_t i = 0; i < list->size; i++)
    {
       memcpy(newbase+i,list->base+i,sizeof(elemType));
    }
    free(list->base);
    list->base=newbase;
    list->capacity=list->size;
 return 0;
}

int main(int argc, char const **argv)
{
    seqList* list=NULL;
    seqList* newList=NULL;
    elemType *item =NULL;
    list=createSeqList(SEQLIST_INIT_SIZE);            
    int select = 1;
    int pos=-1;
    int rel=0;
    char cmd[100];
    char key[100];
    char value[100];
    


    while (select)
    {
        /* code */ 
        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] rever        *\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;32m %s please Enter :>\e[0m",CAPTION);
        scanf("%d", &select); 
        switch (select)
        {
        
        case 0: //quit            
            printf("\e[1;31m SeqList goodbye!\n\e[0m");            
            return 0;
        case 1:    //insert_pos
            pos=list->size;             
            printf("Please enter the insertion position [%d]  ",pos); 
            /*****************************
             * 只需按Enter键即可使用scanf接受默认值
             * char cmd[100];
             * scanf("%c",cmd);
             * scanf("%[^\n]",cmd);
             * ***************************/             
            scanf("%c",cmd); scanf("%[^\n]",cmd); 
            if(cmd[0]>=0x30 && cmd[0]<=0x39 )  {pos=atoi(cmd);}   
            if((item=phoneNote_scanf())==NULL)
            { printf("insert failed,Element is empty\n");break; }        
            if(insertSeqList(list,item,pos)==0) {m_print(list);} 
            break;
        case 2: //delete_pos
        pos=list->size-1; 
        printf("Please enter the delete position [%d]  ",pos);           
            scanf("%c",cmd); scanf("%[^\n]",cmd); 
            if(cmd[0]>=0x30 && cmd[0]<=0x39 ) {pos=atoi(cmd);}            
            if(NULL!=deleteSeqList(list,pos)) { m_print(list); }  
            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")+1); 
            m_sort(list,key);
            m_print(list);
            break;
        case 6: //resver
            m_resver(list);
            m_print(list);
            break;
        case 7:  //clear
            clearSeqList(list);
            m_print(list);
            break; 
        case 8:  //merge            
            list=mergeSeqList(list,list);
            m_print(list);
            break;
        case 9: //reduce        
            reduceSeqList(list,1);
            m_print(list);           
            break;
        case 10:  //delete_val
            printf("Please enter the delete key    ");scanf("%s",key); 
            printf("Please enter the delete value    ");scanf("%s",value);            
            list=m_search(list,key,value,1);          
            m_print(list);         
            break;
        case 11:    //load 
            loadSeqList(list,m_data);
            printf("\e[1;31m load successful \n\e[0m");
            m_print(list);
            break;
        case 12:    //save
            saveSeqList(list,m_data);
            printf("\e[1;31m save successful \n\e[0m");
            break;
        case 13:  //modify
            pos=list->size-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;
        }
    returnSeqList();    
    }
    destroySeqList(&list);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值