1. 程式人生 > >線性表的實現及其基本操作

線性表的實現及其基本操作

  1. 線性表的定義
    線性表是最簡單最常用的一種資料結構,它是一種能在任意位置進行插入和刪除資料元素操作的、由n(n>=0)個相同資料元素組成的線性結構。
  2. 線性表的抽象資料型別
    資料集合
    線性表的資料集合可以表示為a0, a1, a2, a3, ……, an-1,每個資料元素的資料型別都是抽象資料元素的資料型別ElemType。
    操作集合(在此僅羅列一部分,詳細內容請看程式碼塊)
    a. 初始化 InitiateList(L):初始化線性表L
    b. 求當前資料元素個數ListLebgth(L)
    c. 插入資料元素ListInset(L, i, x): 線上性表L的第i個數據元素前插入資料元素x
    d. 刪除資料元素ListDelete(L, i, x):刪除線性表第i個數據元素x
    e. 取資料元素ListGet(L, i, x): 取線性表的第i個數據元素x
//順序表相關操作標頭檔案
#define  ElemType  int
#include<malloc.h>
#include<string.h>

#define SIZE 10
#define NEWSIZE 4

typedef struct SeqList
{
    ElemType *base;      //順序表空間,指的是為順序表在記憶體中動態申請的空間
    size_t capacity;     //順序表的容量
    size_t length;       //順序表的長度,即元素的個數
}SeqList;


int NewSpace(SeqList *list
) //尾插時需要申請新的空間 { ElemType *newspace = (ElemType*)malloc(sizeof(ElemType)*(list->capacity + NEWSIZE)); if(newspace == NULL) { printf("Out Of Memory!\n"); return 0; } memcpy(newspace, list->base, sizeof(ElemType)*list->capacity); //將新申請的空間作為新的順序表空間,並且將原來的順序表空間釋放
free(list->base); list->base = newspace; list->capacity += NEWSIZE; return 1; } void InitSeqList(SeqList *list) //順序表的初始化 { list->capacity = SIZE; list->base = (ElemType *)malloc(sizeof(ElemType)*list->capacity); list->length = 0; } int BegInsert(SeqList *list, ElemType a) //頭插元素 { if(list->length >= list->capacity) //判斷順序表的長度是否大於容量 { printf("空間已滿,不能插入!\n"); return 0; } if(NULL == list->base) //判斷順序表是否被置空 如果已經置空就不能插入資料 { printf("out of memory\n"); return 0; } for(int i=list->length; i>0; i--) { list->base[i] = list->base[i-1]; } list->base[0] = a; list->length++; return 1; } int EndInsert(SeqList *list, ElemType a) //尾插元素 { if(NULL == list->base) //判斷順序表是否被置空 如果已經置空就不能插入資料 { printf("out of memory\n"); return 0; } if(list->length >= list->capacity && !NewSpace(list)) //判斷插入後順序表的長度是否大於容量,是否與新申請的空間大小不符 { printf("空間已滿,無法插入!\n"); return 0; } list->base[list->length++] = a; //把插入的值賦給順序表增加的新空間 return 1; } void ShowList(SeqList *list) //順序表的顯示 { for(int i=0; i<list->length; i++) { printf("%d ",list->base[i]); printf(" "); } printf("\n");; } int BegDelete(SeqList *list) // 頭刪元素 { if(list->length == 0) // 判斷是否非空 { printf("順序表已空,無資料可刪!\n"); return 0; } for(int i=0; i<list->length-1; i++) // 頭刪只需讓順序表中的元素從後往前逐個移動 { list->base[i] = list->base[i+1]; } list->length--; return 1; } int EndDelete(SeqList *list) //尾刪元素 { if(list->length == 0) { printf("順序表已空,無資料可刪!\n"); return 0; } list->length--; // 尾部刪除只需將順序表的長度減一即可 return 1; } void SortList(SeqList *list) //對順序表內的資料排序----氣泡排序法 { int i, j; for(i=0; i<list->length; i++) { for(j=0; j<list->length-i-1; j++) { if(list->base[j] > list->base[j+1]) { int temp = list->base[j]; list->base[j] = list->base[j+1]; list->base[j+1] = temp; } } } } int InsertBVal(SeqList *list, ElemType a) //在順序表中按值插入資料 { if(list->length >= list->capacity) //判斷順序表的長度是否大於容量 { printf("空間已滿,不能插入!\n"); return 0; } if(list->length == 0) //如果順序表是空的,則將插入的值當做第一個數 { list->base[0] = a; } else { int pos; for(pos=0; pos<list->length; pos++) { if(list->base[pos] > a) // 找到pos的位置然後跳出 break; } for(int i=list->length; i>pos; i--) { list->base[i] = list->base[i-1]; } list->base[pos] = a; } list->length++; return 1; } int InsertBPos(SeqList *list, int pos, ElemType a) //按照位置插入資料 { if(list->length >= list->capacity) //判斷順序表的長度是否大於容量 { printf("空間已滿,不能插入!\n"); return 0; } if(pos<0 || pos>list->length) { printf("插入元素位置出錯!\n"); return 0; } for(int i=list->length; i>pos; i--) //找出pos的位置,然後將pos到順序表末尾的資料逐個向後移動,最後在pos處將a插入 { list->base[i] = list->base[i-1]; } list->base[pos] = a; list->length++; return 1; } int DelByPos(SeqList *list, int pos) //按照位置刪除元素 { int i; if(list->length == 0) { printf("順序表已空,無資料可刪!\n"); return 0; } for(i=0; i<pos; i++) { if(i == pos) break; } for(i=pos; i<list->length; i++) { list->base[i] = list->base[i+1]; } list->length--; return 1; } int DelByValue(SeqList *list, ElemType a) // 根據數值刪除順序表中的元素 { int i, j; if(list->length == 0) { printf("順序表已空,無資料可刪!\n"); return 0; } for(i=0; i<list->length; i++) { if(list->base[i] == a) // 找到要刪除的資料 break; } for(j=i; j<list->length; j++) //將要刪除的資料之後的資料逐個向前移動 { list->base[j] = list->base[j+1]; } list->length--; return 1; } void FindElem(SeqList *list, ElemType a) //查詢順序表中的某一資料 { int i; if(list->length ==0) { printf("順序表為空,沒有資料!\n"); return; } else { for(i=0; i<list->length; i++) { if(list->base[i] == a) //找到要查詢的資料的位置跳出迴圈,輸出結果 break; } printf("該資料在順序表的%d的位置處\n",i); } } int ListLength(SeqList *list) //求順序表中的資料個數 { printf("該順序表中有%d個數據\n",list->length); // 將順序表的長度打印出來即可 return 1; } void CleanList(SeqList *list) //順序表的清空, 讓順序表的長度為零即可 { if(list->length == 0) { printf("順序表為空!\n"); } else { list->length = 0; printf("順序表已清空!\n"); } } void ReverseShow(SeqList *list) //順序表的逆序輸出 { if(list->length == 0) { printf("順序表為空!\n"); } else { for(int i=list->length-1; i>=0; --i) //注意迴圈條件 順序表的下標從0開始 { printf("%d ",list->base[i]); } printf("\n"); } } void DestroyList(SeqList *list) //順序表的銷燬 { free(list->base); //順序表的記憶體是連續的,只需要將它的空間釋放後再置空就行 list->base = NULL; }
#include<stdio.h>
#include"SeqList.h"


//順序表操作測試
void main()
{
    SeqList list;
    InitSeqList(&list);

    ElemType x;
    int pos;
    int select = 1;
    while(select)
    {
        printf("*************************************************\n");
        printf("*[1] BegInsert   [2] EndInsert   [3] ShowList   *\n");
        printf("*[4] BegDelete   [5] EndDelete   [6] SortList   *\n");
        printf("*[7] InsertBPos  [8] InsertBVal  [9] DelByPos   *\n");
        printf("*[10]DelByValue  [11]FindElem    [12]ListLength *\n");
        printf("*[13]CleanList   [14]ReverseShow [15]DestroyList*\n");
        printf("*************** [0] QuitSystem ******************\n");
        printf("*************************************************\n");
        printf("請選擇:  ");
        scanf("%d",&select);
        switch(select)
        {
        case 0:
            break;
        case 1:
            printf("請輸入要插入的資料(以-1結束):> ");
            while(scanf("%d",&x),x != -1)
            {
                BegInsert(&list, x);
            }
            break;
        case 2:
            printf("請輸入要插入的資料(以-1結束):> ");
            while(scanf("%d",&x),x != -1)
            {
                EndInsert(&list, x);
            }
            break;
        case 3:
            ShowList(&list);
            break;
        case 4:
            BegDelete(&list);
            break;
        case 5:
            EndDelete(&list);
            break;
        case 6:
            SortList(&list);
            break;
        case 7:
            printf("請輸入要插入的資料:> ");
            scanf("%d",&x);
            printf("請輸入要插入的位置:> ");
            scanf("%d",&pos);
            InsertBPos(&list, pos, x);
            break;
        case 8:
            SortList(&list);
            printf("請輸入要插入的資料:> ");
            scanf("%d",&x);
            InsertBVal(&list, x);
            break;
        case 9:
            printf("請輸入位置:> ");
            scanf("%d",&pos);
            DelByPos(&list, pos);
            break;
        case 10:
            printf("請輸入要刪除的元素:> ");
            scanf("%d",&x);
            DelByValue(&list, x);
            break;
        case 11:
            printf("請輸入要查詢的資料:> ");
            scanf("%d", &x);
            FindElem(&list, x);
            break;
        case 12:
            ListLength(&list);
            break;
        case 13:
            CleanList(&list);
            break;
        case 14:
            ReverseShow(&list);
            break;
        case 15:
            DestroyList(&list);
            break;
        }
    }

}