C語言 數據結構與算法 線性表

數據結構中邏輯結構分線性和非線性。數據結構

線性表即爲線性結構中的一種。
測試

線性表的特性 百度百科解釋在此url

我的總結爲 善始善終,順序排列,首尾不相連(像火車同樣)。spa

線性表的基本操做以下:code

初始化,銷燬,重置爲空表,判斷是否爲空,查找表的長度,element

查找元素的位置,根據位置查找元素,查找元素的上一個元素,查找元素的下一個元素,get

插入元素,刪除元素,遍歷元素。it

下面是順序存儲結構的C實現。(有時間能夠嘗試下鏈式存儲結構的實現)io

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INIT_SIZE 10        //初始化表長度
#define INCREMENT_SIZE 5    //增量

typedef int Status;
typedef int Elemtype;

/*
 * 數據存貯結構
 */
typedef struct
{
    Elemtype *elem;    //存儲空間基址
    int length;        //當前長度
    int size;        //當前分配的表長大小
}SqList;

/*
 * 初始化線性表
 */
Status InitList(SqList *L)
{
    L->elem = (Elemtype *) malloc(INIT_SIZE * sizeof(Elemtype));
    if (!L->elem)
    {
        return ERROR;
    }
    L->length = 0;
    L->size = INIT_SIZE;
    return OK;
}

/*
 * 銷燬
 */
Status DestroyList(SqList *L)
{
    free(L->elem);
    L->length = 0;
    L->size = 0;
    return OK;
}

/*
 * 清空
 */
Status ClearList(SqList *L)
{
    L->length = 0;
    return OK;
}

/*
 * 是否爲空
 */
Status isEmpty(const SqList L)
{
    if (0 == L.length)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/*
 * 獲取表長
 */
Status getLength(const SqList L)
{
    return L.length;
}

/*
 * 獲取指定位置的元素
 */
Status GetElem(const SqList L, int i, Elemtype *e)
{
    if (i < 1 || i > L.length)
    {
        return ERROR;
    }
    *e = L.elem[i-1];
    return OK;
}

/*
 * 比較元素大小
 */
Status compare(Elemtype e1, Elemtype e2)
{
    if (e1 == e2)
    {
        return 0;
    }
    else if (e1 < e2)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

/*
 * 查找元素的位置
 */
Status FindElem(const SqList L, Elemtype e, Status (*compare)(Elemtype, Elemtype))
{
    int i;
    for (i = 0; i < L.length; i++)
    {
        if (!(*compare)(L.elem[i], e))
        {
            return i + 1;
        }
    }
    if (i >= L.length)
    {
        return ERROR;
    }
}

/*
 * 查找當前元素的前一個元素
 */
Status PreElem(const SqList L, Elemtype cur_e, Elemtype *pre_e)
{
    int i;
    for (i = 0; i < L.length; i++)
    {
        if (cur_e == L.elem[i])
        {
            if (i != 0)
            {
                *pre_e = L.elem[i - 1];
            }
            else
            {
                return ERROR;
            }
        }
    }
    if (i >= L.length)
    {
        return ERROR;
    }
}

/*
 * 查找當前元素的下一個元素
 */
Status NextElem(const SqList L, Elemtype cur_e, Elemtype *next_e)
{
    int i;
    for (i = 0; i < L.length; i++)
    {
        if (cur_e == L.elem[i])
        {
            if (i < L.length - 1)
            {
                *next_e = L.elem[i + 1];
                return OK;
            }
            else
            {
                return ERROR;
            }
        }
    }
    if (i >= L.length)
    {
        return ERROR;
    }
}

/*
 * 插入元素
 */
Status InsertElem(SqList *L, int i, Elemtype e)
{
    Elemtype *new;
    if (i < 1 || i > L->length + 1)
    {
        return ERROR;
    }
    if (L->length >= L->size)
    {
        new = (Elemtype*) realloc(L->elem, (L->size + INCREMENT_SIZE) * sizeof(Elemtype));
        if (!new)
        {
            return ERROR;
        }
        L->elem = new;
        L->size += INCREMENT_SIZE;
    }
    Elemtype *p = &L->elem[i - 1];
    Elemtype *q = &L->elem[L->length - 1];
    for (; q >= p; q--)
    {
        *(q + 1) = *q;
    }
    *p = e;
    ++L->length;
    return OK;
}

/*
 * 刪除元素
 */
Status DeleteElem(SqList *L, int i, Elemtype *e)
{
    if (i < 1 || i > L->length)
    {
        return ERROR;
    }
    Elemtype *p = &L->elem[i - 1];
    *e = *p;
    for (; p < &L->elem[L->length]; p++)
    {
        *(p) = *(p + 1);
    }
    --L->length;
    return OK;
}

/*
 * 訪問元素
 */
void visit(Elemtype e)
{
    printf("%d ", e);
}

/*
 * 遍歷表
 */
Status TraverseList(const SqList L, void (*visit)(Elemtype))
{
    int i;
    for(i = 0; i < L.length; i++)
    {
        visit(L.elem[i]);
    }
    return OK;
}

//測試
int main()
{
    SqList L;
    if (InitList(&L))
    {
        Elemtype e;
        printf("init_success\n");
        int i;
        for (i=0; i<10; i++)
        {
             InsertElem(&L, i+1, i);
        }
        printf("length is %d\n", getLength(L));
        if (GetElem(L, 1, &e)) {
        printf("This first element is %d\n", e);
        }
        else
        {
            printf("element id not exist\n");
        }
        printf("The 5 at %d\n", FindElem(L, 5, *compare));
        PreElem(L, 6, &e);
        printf("The 6's previoud element is %d\n",e);
        NextElem(L, 6, &e);
     printf("The 6's next element is %d\n", e);
        DeleteElem(&L, 1, &e);
        printf("delete first element is %d\n",e);
        TraverseList(L, visit);
    if (DestroyList(&L))
    {
        printf("\ndestory_success");
    }
    }
}

  看了幾遍 終於通了,對新手來講其中比較難理解的地方就是插入元素 那個操做裏的 位移操做 舉例以下class

list 裏本來有 1 2  3 4 5  當須要插入 6 到 第二個位置 須要把 2 3 4 5 都日後移動 可是在上面的代碼裏移動的是元素地址 從最後一個開始 從高位往地位移動 因此比較難理解。

相關文章
相關標籤/搜索