計算機考研之數據結構-線性表

數據結構-線性表

抽象描述

定義

  1. 元素爲單個的數據元素
  2. 元素個數有限
  3. 元素數據類型相同
  4. 有邏輯上的前後關係
    • 每一個元素有且僅有一個直接前驅
    • 除最後一個元素之外,每一個元素有且僅有一個直接後繼

操做

InitList(&L),構造一個空的線性表。
Length(L),返回線性表長度。
LocateElem(L,e),根據值查找元素。
GetElem(L,i),根據索引查找元素。
ListInsert(&L,i,e),在指定索引處插入元素。
ListDelete(&L,i,&e),刪除指定索引處的元素,並使用引用返回刪除元素的值。
PrintList(L),順序輸出線性表索引的元素。
Empty(L),判斷線性表是否爲空。
DestroyList,銷燬線性表。數組

順序表

線性表的順序存儲結構稱之爲順序表。
相對於鏈表,順序表最重要的特徵是隨機訪問,即順序表能夠使用O(1)的時間找到指定索引的元素。數據結構

定義

靜態定義:指針

#define MAX 50
typedef struct{
    int data[MAX];
    int length;
}SqList;

動態定義:code

#define InitSize 100
typedef struct{
    int *data; //指向動態分配數組的指針
    int MAX, length;
}SqList;

L.data = (int*)malloc(sizeof(int)*InitSize) //c的動態分配方式
L.data = new int[InitSize] //c++的動態分配方式

操做

這裏分清楚次序與數組下標或者說索引,次序從1開始,數組下標從0開始,咱們這裏默認i是索引。MAX索引

插入,複雜度O(n)。it

bool ListInsert(SqList &L, int i, int e){
    if(!(i>=0 && i<L.length)) return false;
    if(L.length>=MAX) return false;
    for(int j=L.length; j>=i+1; j--) 
        L.data[j] = L.data[j-1];
    L.data[i] = e
    L.length++;
    return true;
}

刪除,複雜度O(n)。io

bool ListDelete(SqList &L, int i, int &e){
    if(!(i>=0 && i<L.length)) return false;
    e = L.data[i];
    for(int j=i-1, j<L.length-1; j++){
        L.data[j-1]=L.data[j];
    }
    L.length--;
    return true;
}

值查找class

bool LocateElem(SqList L, int e, int& i)
    int j;
    for(j=0; i<L.length; i++)
        if(L.data[j] == e){
            i = j;
            return true;
        }
    return false;
}

單鏈表

線性表的鏈式存儲結構稱之爲鏈表。List

定義

typedef struct LNode{
    int data;
    struct LNode *next;
}LNode, *LinkList;

一般使用頭指針來表示一個鏈表。爲了操做上的方便有的時候也會在頭指針以前附加一個頭結點。
頭結點通常不存儲數據。
下面的全部操做都是以有頭結點爲例子的。

操做

  1. 頭插法創建鏈表
    c LinkList CreatList(LinkList &L){ LNode *s; int x; L=(LinkList)malloc(sizeof(LNode)); //建立頭結點 L->next=NULL; while(scanf("%d", &x)){ s=(LNode*)malloc(sizeof(LNode)); s->data=x; s->next=L->next; L->next=s; } return L; }

  2. 尾插法
    c LinkList CreatList(LinkList &L){ LNode *s, *r; int x; // r爲指向表尾的指針 L=(LinkList)malloc(sizeof(LNode)); //建立頭結點 L->next=NULL; while(scanf("%d", &x)){ s=(LNode*)malloc(sizeof(LNode)); s->data=x; r->next=s; r=s; } r->next=NULL; // 尾結點置空 return L; }

  3. 序號索引
    c LNode* GetElem(LinkList L, int i){ if(i<0) return NULL; if(i==0) return L; int j=1; LNode* p=L->next; while(p&&j<i){ p=p->next; j++; } return p; }

  4. 插入結點
    c p=GetElem(L, i-1); s->next=p->next; p->next=s;

  5. 刪除結點
    c p=GetElem(L,i-1); q=p->next; p->next=q->next; free(q);

雙鏈表

定義

typedef struct DNode{
    int data;
    struct DNode *prior;
    struct DNode *next;
}

操做

  1. 插入,在p後插入一個s節點
    c s->next=p->next; p->next->prior=s; s->prior=p; p->next=s;

  2. 刪除一個p以後的q節點
    c p->next=q->next; q->next->prior=p; free(q);

小結

關於順序表和鏈表的一些重要的比較:

  1. 存取方式
    • 順序表能夠順序存儲,也能夠隨機存儲,可是鏈表只能順序存儲。
  2. 增刪查操做
    • 鏈表的單獨的增刪操做都是O(1),索引查找爲O(n)。而順序表反之,索引查找O(1),增刪操做O(n)。

因此,順序表適合查找場景,鏈表適合頻繁增刪的場景。

習題

暫空。

相關文章
相關標籤/搜索