線性表是最基本、最簡單、也是最常用的一種資料結構。線性表中資料元素之間的關係是一對一的關係,即除了第一個和最後一個資料元素之外,其它資料元素都是首尾相接的。線性表的邏輯結構簡單,便於實現和操作。因此,線性表這種資料結構在實際應用中是廣泛採用的一種資料結構。
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; }
這其實是昨天回顧的,今天早上才有時間發篇部落格~~