線性表是一種經常使用的數據結構。在實際應用中,線性表都是以棧、隊列、字符串、數組等特殊線性表的形式來使用的。因爲這些特殊線性表都具備各自的特性,所以,掌握這些特殊線性表的特性,對於數據運算的可靠性和提升操做效率都是相當重要的。 線性表是一個線性結構,它是一個含有n≥0個結點的有限序列,對於其中的結點,有且僅有一個開始結點沒有前驅但有一個後繼結點,有且僅有一個終端結點沒有後繼但有一個前驅結點,其它的結點都有且僅有一個前驅和一個後繼結點。java
特徵:node
1.集合中必存在惟一的一個「第一元素」;
2.集合中必存在惟一的一個 「最後元素」 ;
3.除最後一個元素以外,均有 惟一的後繼(後件);
4.除第一個元素以外,均有 惟一的前驅(前件)。c++
java中的List接口,就是線性表。ArrayList就是順序線性表,LinkedList就是鏈表線性表。數組
通常使用數組(C語言中的數組採用順序存儲方式。即連續地址存儲)來描述。數據結構
優勢:在於隨機訪問元素,app
缺點:插入和和刪除的時候,須要移動大量的元素。ide
c語言實現代碼:ui
// Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include "stdlib.h" //宏定義 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define LT(a,b) ((a)<(b)) #define N = 100 #define LIST_INIT_SIZE 100 //線性表初始空間分配量 #define LISTINCREMENT 10 //線性表空間分配的增量 typedef int Status; typedef int ElemType; typedef struct LNode{ ElemType *elem; //存儲空間的基地址 int lenght; //當前的長度 int listsize; //當前分配的存儲容量 }SqList; /** *構造空的線性表 */ Status initList(SqList &L, int lenght){ if (lenght == 0) lenght = LIST_INIT_SIZE; L.elem = (ElemType *)malloc(lenght * sizeof(ElemType)); if(!L.elem) exit(OVERFLOW); //分配存儲空間失敗 L.lenght = 0; //初始空表長度爲0 L.listsize = lenght ;//初始存儲容量爲100 return OK; } /************************************************************************/ /* 在第i位置插入e */ /************************************************************************/ Status insertList(SqList &L, ElemType e, int i){ ElemType *p, *q; if(i<0 ||i > L.lenght) return ERROR; //i值不合法 if (L.lenght >= L.listsize) { ElemType *newbase = (ElemType *)realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType)); if(!newbase) return OVERFLOW; //存儲分配失敗 L.elem = newbase; //新基值 L.listsize += LISTINCREMENT; //增長存儲容量 } q = &L.elem[i]; //q爲插入的位置 for (p = &L.elem[L.lenght]; p>=q; --p) { *p = *(p-1); //i元素以後的元素日後移動 } *q = e; //插入e L.lenght +=1; return OK; } /************************************************************************/ /* 快速排序 */ /************************************************************************/ void sortList(SqList &L){ } /************************************************************************/ /* 刪除第i位置元素,並用e返回其值 */ /************************************************************************/ Status deleteListElem(SqList &L, int i, ElemType &e){ int *p, *q; if(i<0 ||i > L.lenght) return ERROR; //i值不合法 q = &L.elem[i]; //被刪除元素的位置爲i,L.elem就是數組名, e = *q; //被刪除元素的值賦值給e for (p = q; p< (L.elem + L.lenght); p++){ //元素左移 *p = *(p+1); } --L.lenght; return OK; } /************************************************************************/ /* 快速排序 */ /************************************************************************/ int partition(SqList &L, ElemType low, ElemType high){ ElemType pivotkey = L.elem[low]; //樞軸記錄關鍵字 while (low < high) { //從表的兩端向中間掃描 while (low < high && L.elem[high] >= pivotkey ) --high;//高端位置掃描 L.elem[low] = L.elem[high]; //交換數據,小於pivotkey移到低端 L.elem[high] = pivotkey; while (low < high && L.elem[low] <= pivotkey ) ++low; //低端掃描 L.elem[high] = L.elem[low]; //交換數據 大於pivotkey移到高端 L.elem[low] = pivotkey; } return low; } void quickSort(SqList &L, ElemType low, ElemType high){ int pivot; if(low < high) { pivot = partition(L, low, high); quickSort(L, low, pivot -1); //低端子表排序 quickSort(L, pivot +1, high); //高端子表排序 } } /************************************************************************/ /* 合併兩個線性表 */ /************************************************************************/ void mergeList(SqList La, SqList Lb, SqList &Lc){ ElemType *pa, *pb, *pc; Lc.listsize = La.lenght + Lb.lenght; initList(Lc, Lc.listsize); //初始化LC\pc = Lc.elem; Lc.lenght = Lc.listsize; pc = Lc.elem; pa = La.elem; pb = Lb.elem; while (pa <= &La.elem[La.lenght -1] && pb <= &Lb.elem[Lb.lenght -1]){ if (*pa <= *pb) *pc++ = *pa++; else *pc++ = *pb++; } while(pa <= &La.elem[La.lenght -1]) *pc++ = *pa++; //插入La的剩餘元素 while(pb <= &Lb.elem[Lb.lenght -1]) *pc++ = *pb++; //插入Lb的剩餘元素 } /************************************************************************/ /* 打印list */ /************************************************************************/ void printList(SqList L){ printf("當前值:"); for (int i =0; i<L.lenght;i++) { printf("%d ", *(L.elem+i)); // L.elem爲首地址 } printf("\r\n"); } void main() { SqList La,Lb,Lc; ElemType e; int init,i; init = initList(La, LIST_INIT_SIZE); int data[6] = {5,3,6,2,7,4}; for (i=0; i<6;i++) { insertList(La, data[i], i); } printf("LA:\r\n"); printList(La); deleteListElem(La, 3, e ); printList(La); insertList(La, e, 3); printList(La); //排序 quickSort(La,0, La.lenght-1); printList(La); printf("LB:\r\n"); initList(Lb, LIST_INIT_SIZE); int Bdata[5] = {1,3,2,4,6}; for (i=0; i<5;i++) { insertList(Lb, Bdata[i], i); } //排序 quickSort(Lb,0, Lb.lenght-1); printList(Lb); mergeList(La, Lb, Lc); printList(Lc); }
通常使用鏈表來描述。spa
優勢:對於新增和刪除操做add和remove和方便。不須要移動元素。指針
缺點:不方便隨機訪問元素,LinkedList要移動指針
代碼實現:
1 // Test.cpp : Defines the entry point for the console application. 2 // 3 #include "stdafx.h" 4 #include <stdio.h> 5 #include "stdlib.h" 6 //宏定義 7 #define TRUE 1 8 #define FALSE 0 9 #define OK 1 10 #define ERROR 0 11 #define INFEASIBLE -1 12 #define OVERFLOW -2 13 14 #define LT(a,b) ((a)<(b)) 15 #define N = 100 16 17 typedef int Status; 18 typedef int ElemType; 19 20 typedef struct LNode{ 21 ElemType data; 22 struct LNode *next; 23 }LNode, *LinkList; 24 25 /************************************************************************/ 26 /* 27 初始化鏈表 28 */ 29 /************************************************************************/ 30 Status initList(LinkList &L){ 31 /*單鏈表的初始化*/ 32 L = (LinkList)malloc(sizeof(LNode)); //申請一個頭節點 33 if(!L) exit(OVERFLOW); //申請空間失敗 34 L->next=NULL; //創建一個帶都節點的空鏈表 35 return OK; 36 37 /* 38 須要改變指針的指針,因此參數必須是引用或者是 *L: 39 (*L) = (Lnode *)malloc(sizeof(Lnode)); 40 (*L)->next=NULL; 41 return 1; 42 */ 43 44 } 45 46 /************************************************************************/ 47 /* 48 建立鏈表 49 */ 50 /************************************************************************/ 51 void createList(LinkList L, int n){ 52 /*單鏈表的初始化*/ 53 if (!L) { 54 initList(L); 55 } 56 ElemType data; 57 LinkList p,q = L; 58 printf("輸入節點數據的個數%d:\r\n", n); 59 for(int i = 0; i<n; i++) { 60 p = (LinkList) malloc( sizeof(LNode)); //申請一個新節點 61 scanf("%d",&data); 62 p->data = data; 63 p->next = q->next; 64 q->next = p; 65 q = p; 66 } 67 } 68 /************************************************************************/ 69 /* 在第i位置插入e 70 */ 71 /************************************************************************/ 72 Status insertList(LinkList L, ElemType e, int i){ 73 LinkList s, p = L; 74 int j = 0; 75 while (p && j<i){ //尋找i節點 76 p = p->next; 77 j++; 78 } 79 if (!p ||j >i) return ERROR; 80 s = (LinkList) malloc(sizeof(LNode)); //生成新節點 81 s->data = e; s->next = p->next; //插入L中 82 p->next = s; 83 return OK; 84 85 } 86 87 /************************************************************************/ 88 /* 刪除第i位置元素,並用e返回其值 */ 89 /************************************************************************/ 90 Status deleteListElem(LinkList L, int i, ElemType &e){ 91 LinkList p, q; 92 int j = 0; 93 p = L; 94 while (p && j<i){ 95 p = p->next; 96 ++j; 97 } 98 if (!p->next || j>i) return ERROR; //刪除的位置不對 99 q = p->next; p->next = q->next; 100 e = q->data; free(q); //釋放節點 101 return OK; 102 } 103 104 105 /************************************************************************/ 106 /* 插入排序 107 */ 108 /************************************************************************/ 109 110 void InsertSort(LinkList L) 111 { 112 LinkList list; /*爲原鏈表剩下用於直接插入排序的節點頭指針*/ 113 LinkList node; /*插入節點*/ 114 LinkList p; 115 LinkList q; 116 117 list = L->next; /*原鏈表剩下用於直接插入排序的節點鏈表*/ 118 L->next = NULL; /*只含有一個節點的鏈表的有序鏈表。*/ 119 while (list != NULL) { /*遍歷剩下無序的鏈表*/ 120 node = list, q = L; 121 while (q && node->data > q->data ) { 122 p = q; 123 q = q->next; 124 } 125 126 if (q == L) { /*插在第一個節點以前*/ 127 L = node; 128 } else { /*p是q的前驅*/ 129 p->next = node; 130 } 131 list = list->next; 132 node->next = q; /*完成插入動做*/ 133 134 } 135 } 136 137 138 139 /************************************************************************/ 140 /* 141 合併兩個線性表 142 */ 143 /************************************************************************/ 144 145 void mergeList(LinkList &La, LinkList &Lb, LinkList &Lc){ 146 LinkList pa, pb, pc; 147 pa = La->next; 148 pb = Lb->next; 149 Lc = pc = La; 150 while (pa && pa) { 151 if (pa->data > pb->data) { 152 pc->next = pb; 153 pc = pb; 154 pb =pb->next; 155 }else{ 156 pc->next = pa; 157 pc = pa; 158 pa =pa->next; 159 } 160 } 161 pc->next = pa? pa :pb; 162 free(Lb); 163 } 164 165 /************************************************************************/ 166 /* 打印list 167 */ 168 /************************************************************************/ 169 void printList(LinkList L){ 170 printf("當前值:"); 171 LinkList p; 172 p = L->next; 173 while(p){ 174 printf("%d ", p->data); 175 p = p->next; 176 } 177 printf("\r\n"); 178 } 179 180 void main() 181 { 182 LinkList La,Lb,Lc; 183 ElemType e; 184 int init,i; 185 printf("LA:\r\n"); 186 initList(La); 187 createList(La, 5); 188 insertList(La, 7, 3); 189 printList(La); 190 deleteListElem(La, 3, e); 191 printList(La); 192 InsertSort(La); 193 printList(La); 194 195 printf("Lb:\r\n"); 196 initList(Lb); 197 createList(Lb, 4); 198 InsertSort(Lb); 199 printList(Lb); 200 201 printf("Lc:\r\n"); 202 initList(Lc); 203 mergeList(La, Lb, Lc); 204 printList(Lc); 205 206 }