演算法與資料結構(1)--線性表

weixin_33831673發表於2013-12-12

線性表是最基本、最簡單、也是最常用的一種資料結構。線性表中資料元素之間的關係是一對一的關係,即除了第一個和最後一個資料元素之外,其它資料元素都是首尾相接的。線性表的邏輯結構簡單,便於實現和操作。因此,線性表這種資料結構在實際應用中是廣泛採用的一種資料結構。


1結構

線性表是一種常用的資料結構,以下介紹線性表及其順序儲存,並對棧和佇列及它們的順序實現給出了詳細的設計描述。
在實際應用中,線性表都是以棧、佇列、字串等特殊線性表的形式來使用的。由於這些特殊線性表都具有各自的特性,因此,掌握這些特殊線性表的特性,對於資料運算的可靠性和提高操作效率都是至關重要的。
線性表是一個線性結構,它是一個含有n≥0個結點的有限序列,對於其中的結點,有且僅有一個開始結點沒有前驅但有一個後繼結點,有且僅有一個終端結點沒有後繼但有一個前驅結點,其它的結點都有且僅有一個前驅和一個後繼結點。一般地,一個線性表可以表示成一個線性序列:k1,k2,…,kn,其中k1是開始結點,kn是終端結點。
是一個資料元素的有序(次序)集


2特徵

線性結構的基本特徵為:
1.集合中必存在唯一的一個“第一元素”;
2.集合中必存在唯一的一個 “最後元素” ;
3.除最後一個元素之外,均有 唯一的後繼(後件);
4.除第一個元素之外,均有 唯一的前驅(前件)。
由n(n≥0)個資料元素(結點)a1,a2,…,an組成的有限序列。
資料元素的個數n定義為表的長度。
當n=0時稱為空表。
常常將非空的線性表(n>0)記作:
(a1,a2,…an)
資料元素ai(1≦i≦n)只是一個抽象的符號,其具體含義在不同的情況下可以不同。
線性表的基本操作

1) MakeEmpty(L) 這是一個將L變為空表的方法
2) Length(L) 返回表L的長度,即表中元素個數
3) Get(L,i) 這是一個函式,函式值為L中位置i處的元素(1≤i≤n)
4) Prev(L,i) 取i的前驅元素
5) Next(L,i) 取i的後繼元素
6) Locate(L,x) 這是一個函式,函式值為元素x在L中的位置
7) Insert(L,i,x)在表L的位置i處插入元素x,將原佔據位置i的元素及後面的元素都向後推一個位置
8) Delete(L,p) 從表L中刪除位置p處的元素
9) IsEmpty(L) 如果表L為空表(長度為0)則返回true,否則返回false
10) Clear(L)清除所有元素
11) Init(L)同第一個,初始化線性表為空
12) Traverse(L)遍歷輸出所有元素
13) Find(L,x)查詢並返回元素
14) Update(L,x)修改元素
15) Sort(L)對所有元素重新按給定的條件排序
16) strstr(string1,string2)用於字元陣列的求string1中出現string2的首地址

回顧程式碼如下

#include "stdio.h"
//線性表的順序儲存結構
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0

typedef struct
{
    int data[MAXSIZE];
    int last;
}SeqList;

// 序表的初始化
SeqList SeqListInit()
{// 構造一個空的線性表L
    SeqList L;  //定義L為順序表
    L.last = 0; //順序表長度為零
    return L;   //返回空順序表
}

// 元素定位
int SeqListLocate(SeqList L, int x)
{// 在順序表L中查詢值為x的元素。若查詢成功,則返回它在順序表中的位序,否則返回-1表示查詢失敗
    int i = 1;
    while(i <= L.last && L.data[i - 1] != x)
    {
        i++;
    }
    if (i <= L.last)
    {
        return i;   // 返回資料元素的位序
    }
    else
    {
        return 0;  // 查詢失敗
    }
}

// 線性表判空
int IsEmpty(SeqList L)
{
    return (L.last == 0 ? TRUE : FALSE);
}

// 插入運算
SeqList SeqListInsert(SeqList L, int i, int x)
{// 在順序表中的第i個位置插入元素x
    int j;
    if(L.last == MAXSIZE)
    {
        printf("表滿\n");            // 表滿,退出
        exit(0);
    }
    if(i < 1 || i > L.last + 1)
    {
        printf("插入位置錯誤\n");     // 插入位置錯,退出
        exit(0);
    }
    for(j = L.last - 1; j >= i - 1; j--)
    {
        L.data[j + 1] = L.data[j];  // 第i個位置後的陣列元素逐一後移
    }
    L.data[i - 1] = x;              // 新元素插入到第i個位置
    L.last++;                       // 順序表長度增1
    return (L);                     // 返回插入元素後的順序表
}

// 刪除運算
SeqList SeqListDelete(SeqList L, int i)
{// 刪除順序表中的第i個元素
    int j;
    if (i < 1 || i > L.last)
    {
        printf("位置非法\n");           // 檢查空表及刪除位置的合法性
        exit(0);
    }
    for(j = i; j <= L.last - 1; j++)
    {
        L.data[j - 1] = L.data[j];      // 向上移動
    }
    L.last--;                           // 順序表長度減1
    return (L);                         // 返回刪除元素後的順序表
}

// 合併非遞減有序順序表
SeqList SeqListMerge(SeqList Sla, SeqList Slb)
{// 將非遞減有序的順序表Sla和Slb合併成一個新的順序表Slc,Slc也是非遞減有序的
    // 初始化
    SeqList Slc;
    Slc.last = 0;
    int i = 0, j = 0, k = -1;
    while(i < Sla.last && j < Slb.last)     // Sla和Slb均非空
    {
        if(Sla.data[i] <= Slb.data[j])
        {
            Slc.data[++k] = Sla.data[i++];  // Sla中元素插入Slc
        }
        else
        {
            Slc.data[++k] = Slb.data[j++];  // Slb中元素插入Slc
        }
    }
    while(i < Sla.last)
    {
        Slc.data[++k] = Sla.data[i++];      // Slb已空,將Sla表的剩餘部分複製到新表
    }
    while(j < Slb.last)
    {
        Slc.data[++k] = Slb.data[j++];      // Sla已空,將Slb表的剩餘部分複製到新表
    }
    Slc.last = k + 1;
    return (Slc);
}

// 展示SeqList的內容
void ShowData(SeqList L)
{
    int i = 0;
    for (; i < L.last; ++i)
    {
        printf("%d\t", L.data[i]);
    }
    printf("\n");
}

int main()
{
    // 測試程式碼
    SeqList l = SeqListInit();
    l = SeqListInsert(l, 1, 20);
    l = SeqListInsert(l, 1, 13);
    l = SeqListInsert(l, 1, 10);
    ShowData(l);
    printf("L.last = %d\n", l.last);

    int x = SeqListLocate(l, 10);
    printf("10 in %d\n", x);


    l = SeqListDelete(l, 2);
    ShowData(l);

    SeqList l2 = SeqListInit();
    l2 = SeqListInsert(l2, 1, 44);
    l2 = SeqListInsert(l2, 1, 23);
    l2 = SeqListInsert(l2, 1, 4);
    ShowData(l2);
    l = SeqListMerge(l, l2);
    ShowData(l);
    return 0;
}

這其實是昨天回顧的,今天早上才有時間發篇部落格~~

相關文章