順序表的應用__電話本

順序表的建立及使用

順序表: 就所謂的數組式操作
編程實現順序存儲結構中的基本操作的實現(電話本的建立、插入、刪除、修改、逆置、查找、輸出)
整個操作過於簡陋, 只對上述功能做敘述, 採用結構體數組實現, 本打算用class操作, 可因爲某種原因就擱置了………..
代碼中的註釋部分是用於測試數據, 電話本只存有number, name

//size全局變量表示電話本當前大小不包含0位置,0號位置作爲中間變量處理, 重新申請中間變量太麻煩了就省略 
//
#include<cstdio>
#include<cstring>
#define MAXSIZE 100
#define null 0

int size=0; //表示當前電話本中有幾個聯繫人的信息

typedef struct{
    char name[10];
    char number[12];
}telephone;

telephone t[MAXSIZE];//創建結構體數組的時候,可採用new,此處對此操作省略
void create();
int find(int lo,int hi,telephone t[],char* target_value);
void insert(telephone t[],int size);
void display(telephone t[],int size);
void convert(telephone t[],int size); 

void create(){
    int t_size;
    printf("輸入需要創建的電話本大小");
    scanf("%d",&t_size);
    insert(t,t_size+1);
//  printf("%d\n",size); 
}

int find(int lo,int hi,telephone t[],char target_value[]){//使用二分查找
    if(lo>=hi)return null;//遞歸基 
    if(strcmp(target_value,t[(lo+hi)/2].name)==0) //遞歸基 
        return (lo+hi)/2;
    if(strcmp(target_value,t[(lo+hi)/2].name)>0)
        return find((lo+hi)/2+1,hi,t,target_value);
    else if(strcmp(target_value,t[(lo+hi)/2].name)<0)
        return find(lo,(lo+hi)/2,t,target_value);

}
//在插入的過程中使用插入排序,以便於find操作
void insert(telephone t[],int t_size){
        int i,j;
        for(i=size+1;i<t_size;i++){
            printf("輸入姓名,電話\n"); 
            scanf("%s%s",t[i].name,t[i].number);//t[0]爲哨兵,作爲每次插入的中間變量
            strcpy(t[0].name,t[i].name);//哨兵元素每次表示要插入的元素(該元素先插到數組的尾部)
            strcpy(t[0].number,t[i].number);
            j=i-1;//此時的j表示待插入元素的前一個元素 
            //待插入的元素比哨兵元素小,進行移動覆蓋,查找到比哨兵元素小的值時
            //將哨兵元素放到此位置
            while((strcmp(t[j].name,t[0].name)>0)){
                strcpy(t[j+1].name,t[j].name);
                strcpy(t[j+1].number,t[j].number);
                j--;
            }
            //此處的j指向剛插入的元素的位置 
            strcpy(t[j+1].name,t[0].name);//哨兵放置 
            strcpy(t[j+1].number,t[0].number); 
            ++size; //每插入一個人的信息,size增加一次
//          printf("當前i=%d insert後size=%d\n",i,size); 
        }
//      printf("insert後size=%d\n",size); 
        return; 
}

int remove(telephone t[],char* target_value,int t_size){
//在刪除的過程中出現,將局部變量的值的名稱設置了和全局變量一致,出現size無法減少的情況 
    int i; 
    int location=find(0,size,t,target_value);
//  printf("find=%d\n",location); 
    if(location==0) return null;
    for(i=location;i<=size;i++){
    //將要刪除的元素進行覆蓋處理,令i=size,可實現將最後一個元素變爲"\0" 
        strcpy(t[i].name,t[i+1].name);
        strcpy(t[i].number,t[i+1].number);
    } 
//  strcpy(t[i].name,"\0");
//  strcpy(t[i].number,"\0");//將要刪除的元素的name.number置爲空串
//  if(location==size){//判斷是否刪除最後一個元素,若是則需要進行對0號元素更新,防止insert出現錯誤
    //  strcpy(t[0].name,t[i-1].name);
    //  strcpy(t[0].number,t[i-1].number);
    //}
    size--;
    return location; 
//  printf("remove後size=%d\n",size); 
}

void display(telephone t[],int size){
    char c;
//可在display中引入倒置, 此處不做敘述
        for(int i=1;i<=size;i++)
        printf("%d=姓名:%s, 號碼:%s\n",i,t[i].name,t[i].number);
    return; 
}

void convert(telephone t[],int size){//倒置處理
    for(int i=1;i<=size/2;i++){
        strcpy(t[0].name,t[i].name);strcpy(t[i].name,t[size-i+1].name);strcpy(t[size-i+1].name,t[0].name);//name做倒置
        strcpy(t[0].number,t[i].number);strcpy(t[i].number,t[size-i+1].number);strcpy(t[size-i+1].number,t[0].number);//number倒置
    }
}

int main(){
    int i,key=1;
    char *c; //用於插入, 刪除時臨時的中間變量, 也可使用數組
    while(key){ 
        printf("1-創建電話本\n 2-插入賬戶信息\n 3-查找號碼\n 4-刪除號碼\n 5-查看所有信息\n 6-將電話本倒置\n 7-關閉\n");
        scanf("%d",&i);
        switch(i){
            case 1:create();fflush(stdin);break;
            if(create_flag==1){ 
                case 2:insert(t,size+2);fflush(stdin);break;//當執行單步插入的時候形參要修改爲在size的基礎上擴大1,但是t[0]並不存數據,所以size+2處理 
                case 3:printf("輸入查找的元素,0表示查找失敗\n 查找的姓名:");scanf("%s",c);printf("所在的位置是%d\n",find(1,size,t,c));fflush(stdin);break;
                case 4:printf("輸入要刪除的元素,0表示刪除失敗\n 刪除的姓名:");scanf("%s",c);printf("刪除元素的位置是%d\n",remove(t,c,size));fflush(stdin);break;
                case 5:display(t,size);fflush(stdin);break;
                case 6:convert(t,size);fflush(stdin);break;
            }else printf("未創建電話本,不可刪除,查找,展示,倒置操作"); 
            case 7: key=0;break; 
        }
    } 

    return 0;
} 

在寫代碼的過程中出現的問題是:

  • 二分查找的時候沒有做尾遞歸處理,導致返回值出現問題, 不能正確的返回出是否查找到當前元素的位置, 處理find((lo+hi)/2+1,hi,t,target_value); 寫成做 (lo+hi)/2; 導致在遞歸查找的過程中出現死遞歸, 不能返回出來
  • 在remove中將局部變量的名稱與全局變量的名稱寫成一樣的(size), 導致size–出錯; 真是愚蠢
  • 進行代碼調試的時候只是從邏輯的角度分析問題, 而沒有寫printf語句觀察程序的運行過程, 細心考慮每個變量的變化情況, 造成無法準確地定位錯誤的位置
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章