1. 程式人生 > >線性表總結(c語言)

線性表總結(c語言)

線性表

線性表特點

  • 存在一個唯一的一個被稱作”第一個”的資料元素
  • 存在唯一的一個被稱做”最後一個”的資料元素
  • 除第一個之外,集合中的每個資料元素均只有一個前驅
  • 除最後一個之外,集合中每個資料元素均只有一個後繼

定義

一個線性表是n個數據元素的有限序列。

演算法設定

順序表和線性連結串列

#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
//順序表
typedef struct{
    ElemType * elem;
    int length;
    int listsize;
}SqList;
//連結串列
typedef struct LNode{ ElemType data; struct LNode *next; }LNode,*LinkList;

基本操作

/*
InitList(&L);    //構造一個空線性表L
DestoryList(&L);  //銷燬線性表
ClearList(&L);    //清空線性表
ListEmpty(L);  //判空
ListLength(K); //返回線性表長度
GetElem(L,i,&e); //傳入L線性表,i索引,返回e

LocateElem(L,e,compare()) //返回第一個與e滿足關係的資料元素位序,不存在則返回0
PriorElem(L,cur_e,&pre_e) //若cur_e是L的資料元素,且不是第一個,則用pre_e返回他的前驅。 NextElem(L,cur_e,&next_e) //若cur_e是L的資料元素,且不是最後一個,用next_e返回他的後繼 ListInsert(&L,i,e) //在L中第i個位置之前插入新的資料元素e,L的長度加1 ListDelete(&L,i,&e) //刪除L的第i個數據元素,並呼叫e返回其值,L的長度減1 ListTraverse(L,visit()) //依次對L的每個資料元素呼叫函式visit()。一旦visit()失敗,則操作失敗
*/

線性表(順序儲存結構)

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

bool compare(ElemType e1,ElemType e2) {
    return e1 == e2 ? TRUE : FALSE;
}

void visit(ElemType e) {
    printf("%d ", e);
}

Status InitList(SqList &L) {
    //創造一個空表
    L.elem = (ElemType *)malloc(sizeof(ElemType)*LIST_INIT_SIZE);
    if (!L.elem)
    {
        exit(OVERFLOW);
    }
    L.length = 0;
    L.listsize = LIST_INIT_SIZE;
    return OK;
}

Status ListEmpty(SqList L)  
{
    //判空
    return L.length == 0 ? TRUE : FALSE;
}

int ListLength(SqList L) 
{
    //返回線性表長度
    return L.length;
}

Status GetElem(SqList L,int i,ElemType &e) //傳入L線性表,i索引,返回e
{
    //先判斷索引的合法性
    if (i < 0 || i >= L.length)
    {
        return FALSE;
    }
    e = L.elem[i];
    return TRUE;
}

void ClearList(SqList &L)    //清空線性表
{
    L.length = 0;
}

void DestoryList(SqList &L)  //銷燬線性表
{
    free(L.elem);
    L.length = L.listsize = 0;
}

int LocateElem(SqList L,ElemType e,bool (*compare)(ElemType,ElemType)) //返回第一個與e滿足關係的資料元素位序,不存在則返回-1  compare
{
    for (int i = 0; i < L.length; i++)
    {
        if (compare(L.elem[i],e))
        {
            return i;
        }
    }
    return -1;
}

Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)  
{
    //若cur_e是L的資料元素,且不是第一個,則用pre_e返回他的前驅。

    for (int i = 1; i < L.length; i++)
    {
        if (L.elem[i] ==  cur_e)
        {
            pre_e = L.elem[i - 1];
            return TRUE;
        }
    }
    return FALSE;
}

Status NextElem(SqList L, ElemType cur_e, ElemType &next_e)  
{
    //若cur_e是L的資料元素,且不是最後一個,用next_e返回他的後繼
    for (int i = 0; i < L.length - 1; i++)
    {
        if (L.elem[i] == cur_e)
        {
            next_e = L.elem[i + 1];
            return TRUE;
        }
    }
    return FALSE;
}  

Status ListInsert(SqList &L,int i,ElemType e)   
{
    //在L中第i個位置之前插入新的資料元素e,L的長度加1
    //1.判斷i的合法性
    if (i < 0|| i > L.length)
    {
        return FALSE;
    }
    //2.判斷線性表長度夠不夠,不夠,realloc
    if (L.listsize == L.length)
    {
        L.listsize += LISTINCREMENT;
        L.elem = (ElemType *)realloc(L.elem, L.listsize);
        if (!L.elem)
        {
            exit(OVERFLOW);
        }
    }
    //3.將i元素向後以一個單位 從後向前移動
    for (int j = L.length; j > i; j--)
    {
        L.elem[j] = L.elem[j - 1];
    }
    //4.插入e
    L.elem[i] = e;
    L.length++;
    return TRUE;
}  

Status ListDelete(SqList &L,int i,ElemType &e)  
{
    //刪除L的第i個數據元素,並呼叫e返回其值,L的長度減1
    //1.判斷i的合法性
    if (i < 0 || i >= L.length)
    {
        return FALSE;
    }
    //2.將索引為i的元素取出來,賦值給e
    e = L.elem[i];

    //3.i後面的元素向前移動1個單位,從前向後移動   j最後位置在倒數第二個位置,索引為L.length - 2
    for (int j = i; j < L.length - 1; j++)
    {
        L.elem[j] = L.elem[j + 1];
    }
    L.length--;
    return TRUE;
}

void ListTraverse(SqList L,void (*visit)(ElemType))  
{
    //依次對L的每個資料元素呼叫函式visit()。一旦visit()失敗,則操作失敗
    for (int i = 0; i < L.length; i++)
    {
        visit(L.elem[i]);
    }
}

線性表(鏈式儲存結構)

2.10指出以下演算法中的錯誤和低效(即費時)之處,並將它改寫為一個及正確又高效的演算法

Status DeleteK(SqList &a, int i,int k) {
    //本過程從順序儲存結構的線性表a中刪除第i個元素起的k個元素  
    if (i < 1|| k < 0|| i+k>a.length)
    {
        return INFEASIBLE;
    }
    else
    {
        for (int count = 0; count < k; count++)
        {
            for (int j = a.length; j >= i + 1; j--) {
                a.elem[j - 1] = a.elem[j];
                a.length--;
            }
        }
    }
    return OK;
}

2.11 設順序表va中的資料元素遞增有序,試寫一演算法,將x插入到順序表的適當位置上,以保持該表的有序性。