第二章 線性表

1. 線性表:n個數據元素的有序集合。

 

線性表是一種經常使用的數據結構。在實際應用中,線性表都是以、隊列、字符串數組等特殊線性表的形式來使用的。因爲這些特殊線性表都具備各自的特性,所以,掌握這些特殊線性表的特性,對於數據運算的可靠性和提升操做效率都是相當重要的。  線性表是一個線性結構,它是一個含有n≥0個結點的有限序列,對於其中的結點,有且僅有一個開始結點沒有前驅但有一個後繼結點,有且僅有一個終端結點沒有後繼但有一個前驅結點,其它的結點都有且僅有一個前驅和一個後繼結點。java

特徵:node

1.集合中必存在惟一的一個「第一元素」;
2.集合中必存在惟一的一個 「最後元素」 ;
3.除最後一個元素以外,均有 惟一的後繼(後件);
4.除第一個元素以外,均有 惟一的前驅(前件)。c++

java中的List接口,就是線性表。ArrayList就是順序線性表,LinkedList就是鏈表線性表。數組

 

2. 線性表的順序表示:ArrayList

 

通常使用數組(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);  
  
}  

3. 線性表的鏈表表示LinkedList

通常使用鏈表來描述。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 }  
相關文章
相關標籤/搜索