線性表的順序儲存C++程式碼實現

shell_nut發表於2019-07-11

  關於線性表的概念,等相關描述請參看《大話資料結構》第三章的內容,

1 概念

  線性表list:零個或多個資料的有限序列。
  可以這麼理解:糖葫蘆都吃過吧,它就相當於一個線性表,每個山楂就相當於線性表中的資料。(這很類似與線性表的順序儲存結構)

  線性表有兩種儲存結構,順序儲存結構和鏈式儲存結構,對線性表的操作包括:初始化,判空,清空,查詢元素(返回元素和返回元素位置),插入,刪除,線性表長度等,今天先放線性表順序儲存結構操作的程式碼實現,有參考高一凡大師的程式碼。

2 程式碼

  程式碼分成三個檔案,一個標頭檔案,兩個cpp檔案,sqlist.h標頭檔案,實現線性表順序儲存結構,函式的宣告,巨集定義等,其中一個sqlist.cpp檔案實現對線性表的操作,另一個sqlist_main.cpp檔案實現測試功能。
  以下程式碼在vs2013中親測有效

標頭檔案sqlist.h

#ifndef _SQLIST_H
#define _SQLIST_H

#define MAXSIZE 10
#define LISTINSREMENT 2
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1

typedef int Status;
typedef int ElemType;

typedef struct
{
    ElemType *elem;
    int length;//當前長度
    int listsize;//分配的總大小(按sizeof(ElemType)的整數倍計)
}Sqlist;

Status InitList(Sqlist* L);
Status DestroyList(Sqlist* L);
Status ListEmpty(Sqlist L);
Status CleanList(Sqlist* L);
int ListLength(Sqlist L);
Status ListInsert(Sqlist* L, int i, ElemType e);
Status ListDelete(Sqlist* L, int i, ElemType* e);
Status GetElem(Sqlist* L, int i, ElemType *e);
Status LocateElem(Sqlist L, ElemType e);

#endif

sqlist.cpp檔案

#include "sqlist.h"
#include <iostream>
#include <assert.h>

using namespace std;

/*init sqlist*/
Status InitList(Sqlist* L)
{
    (*L).elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
    assert(NULL != (*L).elem);

    (*L).length = 0;
    (*L).listsize = MAXSIZE;

    return OK;
}

//destroy list
Status DestroyList(Sqlist* L)
{
    free((*L).elem);
    (*L).elem = NULL;
    (*L).length = 0;
    (*L).listsize = 0;

    return OK;
}

//list is empty return true
Status ListEmpty(Sqlist L)
{
    if (0 == L.length)
        return TRUE;
    else
        return FALSE;
}

//clean list
//前提:順序表存在
Status CleanList(Sqlist* L)
{
    if (NULL != (*L).elem)
    {
        (*L).length = 0;
        return OK;
    }
    else
        return ERROR;
}

//return list length
int ListLength(Sqlist L)
{
    if (NULL != L.elem)
    {
        return L.length;
    }
    else
        return ERROR;
}

//insert elem
//前提:順序表存在
//1 判斷i合法
//2 順序表未滿,若滿,增加記憶體分配
//3 插入時,第i個及之後元素後移
//操作結果在第i個前面插入新元素,長度加1
Status ListInsert(Sqlist* L, int i, ElemType e)
{
    ElemType *newbase = NULL, *p = NULL, *q = NULL;
    if (NULL != (*L).elem)//順序表存在
    {
        assert(!(i < 1 || i >(*L).length + 1));// i 不合法
        if ((*L).listsize <= (*L).length)//分配記憶體不夠
        {
            newbase = (ElemType*)realloc((*L).elem, (((*L).listsize + LISTINSREMENT) * sizeof(ElemType)));
            assert(NULL != newbase);
            (*L).elem = newbase;
            (*L).listsize += LISTINSREMENT;
        }
        q = (*L).elem + i - 1;//新元素存放位置
        for (p = (*L).elem + (*L).length - 1; p >= q; p--)//第i個元素後的元素後移一位
        {
            *(p + 1) = *p;
        }

        *q = e;
        (*L).length++;
        return OK;
    }
    else
        return ERROR;
}


//delete elem 
//前提:順序表存在
//i是否合法
//刪除第i個位置的元素並返回這個值
Status ListDelete(Sqlist* L, int i, ElemType* e)
{
    ElemType *p = NULL;
    if (NULL != (*L).elem)
    {
        assert(!(i < 1 || i >(*L).length));
        p = (*L).elem + i - 1;
        *e = *p;
        for (p; p < (*L).elem + (*L).length - 1; p++)
        {
            *p = *(p + 1);
        }
        (*L).length--;

        return OK;
    }
    else
        return ERROR;
}

//get elem
//前提:順序表存在
//判斷i的合法性
//獲得第i個位置的元素並返回其值
Status GetElem(Sqlist* L, int i, ElemType *e)
{
    ElemType *p = NULL;

    if (NULL != (*L).elem)
    {
        assert(!(i<1 || i>(*L).length));
        p = (*L).elem + i - 1;
        *e = *p;
        return OK;
    }
    else
        return ERROR;
}

//find elem
//前提:順序表存在
//查詢結束後i時候在正確範圍內
//返回元素在表中的序號
Status LocateElem(Sqlist L, ElemType e)
{
    int i = 1;

    if (NULL != L.elem)
    {
        
        while (i <= L.length && !(*L.elem++ == e))
            i++;
        return i;

        /*for (i = 0; i < L.length; i++)
        {
            if (e == L.elem[i])
                break;
        }
        if(i+1 <= L.length )
            return i+1;
        else
            return ERROR;
            思路正確,但不夠簡練
            */
    }
    else
        return ERROR;
}

sqlist_main.cpp檔案

#include "sqlist.h"
#include <iostream>
#include <assert.h>

using namespace std;

int main()
{
    Sqlist SL;
    Status ret;
    int i = 0;
    ElemType e;

    ret = InitList(&SL);
    cout << "init success,ret is: " << ret << endl;

    ret = ListEmpty(SL);
    cout << "return 1 is empty, ret is: " << ret << endl;

    ret = CleanList(&SL);
    cout << "return 1 mean clean success, ret is: " << ret << endl;

    for (i = 1; i < 10; i++)
    {
        ret = ListInsert(&SL, i, i);//從頭到尾插入9個數
        //cout << ret << endl;
    }

    ret = ListDelete(&SL, 2, &e);
    cout << "delete success return 1, ret is " << ret << "e is: " << e << endl;

    for (i = 0; i < SL.length; i++)//列印
    {
        cout << SL.elem[i] << endl;
    }

    ret = ListLength(SL);
    cout << "SL length is: " << ret << endl;

    ret = GetElem(&SL, 3, &e);
    cout << "get success return 1, ret is " << ret << "e is: " << e << endl;

    ret = LocateElem(SL, 4);
    cout << "e loctation is: " << ret << endl;

    ret = DestroyList(&SL);
    cout << "destroy success, ret is: " << ret << endl;

    system("pause");
    return 0;
}

  不當之處請多多指點。

相關文章