數據結構

VisuAlgo!
一,Date Structure的核心技術是分解和抽象
二,基本概念和常用術語

    ①Date是對信息的一種符號表示,包括數字,文檔,記錄,數組,句子,單詞,算式都成為數據。在計算機中,任何能輸入到計算機中的信息都叫做數據。
    ——Date Object是眾多具有相同性質的Date Element的集合
    ②Date Element是Data的基本單位,在計算機科學中作為整體進行考慮和處理。
    ③Date Item是Date Element的最小不可分割單位。
    ④Date Structure是具有一種或多種關系的數據元素的集合,按某種邏輯關系組織起來的一批數據,按照一定的存儲方式存儲在計算機存儲器中,在其之上定義一種運算的集合,就成為一個Date Structure,計算機在存儲數據時,不僅要存儲數據本身,還要存儲數據之間相互的邏輯結構。存儲方式成為物理結構或存儲結構,在邏輯結構上存儲“做什么”,在存儲結構上規定數據“如何做”。

三,邏輯結構
1,邏輯結構通常分為四大類:
集合(無關系)
線性結構(唯一前驅和后繼)
非線性結構:樹形結構(唯一前驅,多后繼),圖形結構(多前驅多后繼)
例如
D={1,2,3,4,5,6} //數據元素的集合
R={r} //對應關系的集合
r={(1,2),(2,3),(3,4),(4,5),(5,6)} //序偶的集合
——關系r是序偶的集合,如名字,有順序的兩個結點,稱為序偶:
①數據元素的集合+數據關系的集合
②每個數據元素成為一個結點
③前一結點稱為后一結點的前驅,反之,則稱為后繼

四,存儲結構
1,計算機的存儲結構是由有限個存儲單元組成,每個單元有唯一的地址,地址連續編碼,多個則稱為存儲區域
2,4種基本存儲方法
①順序存儲:把邏輯上相鄰的元素存儲在物理位置相鄰的位置,邏輯關系由存儲單元的鄰接關系來體現。
②鏈式存儲:將邏輯相鄰的元素不存儲在物理位置相鄰的位置,而是把所占用的存儲單元分為兩部分,一部分存儲數據元素本身,另一部分存儲結點后繼元素的地址。
③索引存儲:存儲節點信息的同時,建立索引表,索引表的每一項包含關鍵字和地址,關鍵字能唯一識別數據元素的數據項,針對數據內容的存儲公式
④散列存儲:以數據結構的關鍵字為自變量,通過散列函數來定向計算該元素的存儲位置,針對數據內容的存儲方式

五,運算集合
1,每種邏輯結構都有一種運算的集合
①引用型運算:不改變原有element的狀態,只進行讀取
②加工型運算:改變原有element的狀態,如內容,個數等。

六,抽象數據類型
1,數據類型
①類型顯示或隱式的規定了在程序執行期間變量的一切可能取值和一切在這些值上可能進行的操作,數據類型就是一組值的集合加上在這些值上進行的操作的集合之和。
②數據結構分兩類,一類是基本類型,是給定的,值不可分解,如int,double;一類是結構類型,其可分解,其值也可分解,如結構體,數組etc.
③一般數據類型又稱為預定義數據類型
2,抽象數據類型
①是一個數學模型以及在它上面定義的一組操作(數據的邏輯結構和其上定義的操作)
②通常由用戶自定義其邏輯結構與操作說明,不考慮結構和操作的具體實現
③特點:使用和實現分離開(類型的定義和其實現分離開)

七,線性表
1,邏輯結構
①L = (a1,a2,a3……an-1,an)
a.數據元素個數n稱為表的長度,n=0時稱為空表
b.非空線性表中,存在唯一一個只有后繼沒前驅的表頭元素,同理,職業前驅沒有后繼的稱為表尾元素
c.除表頭元素有且僅有一個前驅,除表尾元素有且僅有一個后繼
d.表中元素數據類型相同,n的取值個數有限
②操作
a.初始化,構造一個新表
b.求線性表的長度
c.按序號取元素
d.按值查找元素,返回第一個結點的位置,若沒找到,返回一個值代表沒有找到
e.插入
f.刪除
g.清空
2,存儲結構
①順序存儲結構
//簡單直接,所占空間連續,隨機存取任一結點按物理位置相鄰來實現其邏輯結構,叫做順序表
a.定義,在一個結構體中定義一個數組存貯數據元素,用一個length存儲表長
// #define MaxLen 100;
typedef int DataType;
typedef struct
{ DataType data[MaxLen];
int length;
}SeqList;
b.初始化,令L->length = 0;即可
c.求表長,return L->length;即可
d.按位置取結點值,若查找位置小于1或者大于MaxLen返回錯誤,若范圍正確return data[i - 1];即可
e.按值取結點位置,用一個i=0來初始化,用一組循環來比較第data[i]個元素的值是否為所需值,若不是i++若是return i;即是所求值結點所在位置。
f.插入,將每個數據元素依次后移,然后插入新節點,將表長+1
//void InsertList(SsqList * L, DataType e,int i)
{//錯誤檢測
for(int j = L -> length - 1; j >= i - 1;j --)
L- > data[j+1] = L -> data[j];
L -> data[i-1] = e;
L -> length ++;
}
//注意當空間已滿,或插入位置非法時,不可進行插入操作
g.刪除,先去除欲刪除節點,再將i+1……n的元素依次移動到i……n-1
②鏈式存儲結構
散亂,結點次序與物理順序不一定一致,由于第一個結點沒有前驅,要用一個head來存儲頭結點的地址
L=(head,a1,a2,....an)
——應用malloc申請結點變量地址,用free函數來釋放一個結點變量地址
a.單鏈表:
(1).建立set,一個結構體內放一個存放數據內容的變量和一個存放下一個結構體的指針。
——頭插法:在head與a1間插入新結點
——尾插法:在an后插入新結點
(2).查找Locate,單鏈表中不會像順序表中那樣直接按序號找元素,只能從頭指針開始,逐一循環。
——按序查:……
——按值查:……
(3).插入Inser,插入到第i個結點的位置,步驟
one.找到第ai-1個結點的位置
two.創建一個新結點 s
three.新結點指針指向ai
four.令
q指向新結點。
——例如:
ListNode *p, q,s;
int j = 1; p = head;
if(i<1||i>GetLength(head)+1)exit(1);
s=(ListNode )malloc(sizeof(ListNode));
s->data = x;
while(j <= i)
{ q=p;p=p->next;
j++; }
s->next = q->next;
q->next = s;
(4)刪除delete,要刪除結點i,首先找到i-1個結點,用一個指針指向i,然后把i-1個結點的指針指向i+1,最后free指向i的指針
b.循環鏈表,將表中終端結點的指針域指向表頭
(1)沒有NULL指針,終止條件不是p或者p->next是否為空,而是判斷他們是否等于某一特定指針
(2)從任意一結點開始,不止能訪問其后繼結點,能訪問所有結點。
c.雙鏈表,結點結構體中,增加一項指針域
prior,用于存儲上一結點的位置,插入和刪除必須同時修改兩個方向上的指針。
d.靜態鏈表……
e.應用,一元多項式的加法

3線性表總結
①順序表與鏈表,若較為穩定則使用順序表,若需要頻繁的插入或刪除操作,則用鏈表
②線性表初期建表容易,無額外開銷,可以隨機訪問任一結點,缺點是建表初期需要預估大小,插入刪除操作相應繁瑣,需要頻繁的移動數組元素。
③鏈表建表相應復雜,額外開銷未知,不能隨機訪問任一結點,但內存管理完美,執行刪除插入操作復雜度小。
④由于高級語言中沒有指針類型,可以定義一個結構體數組,為數組的每個元素附加一個鏈接指針,從而形成靜態鏈表。
八,堆棧
1.定義
①限定僅在表的一端進行插入刪除的線性表,通常稱插入刪除的一端稱為棧頂,另一端稱為棧底,特點:先進后出,后進先出,故也稱為后進先出表。
2.基本運算
①初始化
②壓棧
③出棧
④判斷空棧
⑤取棧頂元素
3.順序存儲結構(順序棧)
#define Maxsize <存儲數據元素的最大個數>
typedef <棧中元素實際數據類型> SElemType;
typedef struct {
Selemtype data[Maxsize];
int top;
}STACK;
STACK *s;
——習慣上將top = -1表示棧空,top = Maxsize - 1表示棧滿,常稱此處的top為“棧頂指針”,但其實并不是指針類型變量。
①初始化,top=-1.
②壓棧,首先判斷是否棧滿,再通過s->top+1后s->data[s->top]來完成壓棧
③出棧,判斷是否為空棧,再先把s->data[s->top]賦值給指針變量后,后s->top-1
④判斷空棧,判斷s->top是否為-1
⑤取棧頂元素,判斷是否為空棧,再先s->data[s->top]賦值給數據類型變量,后s->top-1
4.鏈式存儲結構(鏈棧)
typedef <棧中元素實際數據類型> SElemType;
typedef struct Snode{
SElemtype data;
struct Snode next;
}LinkSTACK;
LinkSTACK top;
①初始化,malloc函數為top分配內存,再做內存分配成功判斷,若成功top->next=NULL;
②壓棧,為一個
s分配內存空間,判斷是否成功,若成功,頭插法插入鏈表結點
③出棧,判斷是否為空棧,若不是,用一個
s存儲棧頂元素內容,隨后刪除鏈表結點,釋放s的內存地址。
④判斷空棧,判斷s->next是否為NULL
⑤取棧頂元素,判斷是否為空棧,再先s->data[s->top]賦值給數據類型變量,后s->top-1
5.遞歸
①使用遞歸的三種情況
(1).很多函數是遞歸定義的
(2).有些數據結構本身固有遞歸特定,可以利用遞歸來定義
(3).使用遞歸化解更簡單
②兩個限制條件
(1).規模較大的原問題能分解成一個或多個規模較小但具有類似于原問題特性的問題。
(2).存在一個或多個無需分解即可直接求解的最小子問題,經過有限次遞歸后,子問題的規模減至最小。

九,隊列
1,定義
僅限在隊尾進行插入操作,在對頭進行刪除操作的“先進先出”表。
①初始化
②入隊
③出隊
④判斷空隊
⑤取棧頂元素
2,順序存儲結構
typedef 實際元素數據類型 QElemtype;
typedef struct{
QElemType data[Maxsize];
int front,rear;
}QUEUE;

                            ——順序隊結構體中數組低下標一端為隊頭,高下標一端為隊尾
                            ——fornt總是指向對頭元素的前一位置,rear總是指向隊尾元素
                            ——假溢出現象用循環隊列來處理
            ①初始化  : Q->front = Q->rear = 0;
            ②入隊:先判斷是否空隊,然后Q->rear = (Q->rear+1)%Maxsize; 對rear指針指向地方賦值即可
            ③出隊:先判斷是否空隊,然后Q->rear = (Q->rear+1)%Maxsize; 用指針指向front指針指向地方,然后釋放即可。
            ④判斷空隊 :判斷是否Q->front = Q->rear;
            ⑤取隊頭元素:*x = (Q -> data[Q->front+1]) % Maxsize
            ⑥計算隊列成員個數:(rear - front +Maxsize)%Maxsize

3,鏈式存儲結構
typedef 實際元素數據類型 QElemType;
typedef struct qnode{
QElemType data;
struct qnode *next;
}QTYPE;
typedef struct {
QTYPE * front, *rear;
}LinkQUEUE;
LinkQUEUE LQ;

                            ——同時帶有頭指針和尾指針的單鏈表
            ①初始化:新建結點p,申請空間,判斷內存,p->next = NULL; LQ->front = LQ ->rear = p;
            ②入隊:新建結點s,申請空間,判斷內存,s->data = x; s->next = NULL; LQ->rear->next = s; LQ ->rear = s;
            ③出隊:
                            void OutQueue(LinkQUEUE * LQ, QElemType *x)
                            {
                                    QTYPE *p;
                                    if(EmptyQueue(LQ))
                                    {printf("cuowu");
                                    return 0;}
                                    p = LQ->front->next;
                                    *x = p->data;
                                    LQ->front->next = p->next;
                                    if(LQ->front->next == NULL)
                                            LQ->rear = LQ->front;
                                    free(p); 
                             }    
            ④判斷空隊:LQ->front == LQ ->rear?1:0; 
            ⑤取隊頭元素:*x = LQ->front->next->data;

九,串
1,定義
又稱作字符串,形如S = “a1a2a3a4an-1”
①所含字符個數稱為串的長度,主串中任意連續字符組成的子序列稱為串的子串
②字符串以'\0'結束,所以串的實際長度要多1個。串中每個字符占1個字節
2,順序存儲結構
#define MaxLen <最大串長>
typedef struct string{
char str[MaxLen];
int curlen;
};
①判斷Equal,先比較長度是否一樣,再比較每一個字符是否一樣
②鏈接concat,先計算兩個字符串的長度和,將t復制到s后面。
3,鏈式存儲結構
typedef struct Lstring{
char data;
struct Lstring * next;
}Lstring;
①判斷Equal,無視長度,同上
②鏈接concat,無視長度,同上
④求子串Lsubstr,先進行錯誤判斷,找到指定的i位置,開始向后賦值n位給一個新的指針,返回

4,優缺點,即鏈式存儲和順序存儲的老毛病。
5,應用,
1,文本編輯器
2,KMP判子串算法

十,數組
1,定義

            ①數據元素固定,不可后添加刪除。
            ②元素數據類型相同
            ③每個數據元素值有唯一下標對應
            ④隨機存儲結構,隨機存取任意元素
            ⑤數據元素是一個數據結構,可以是線性表中的一個元素,也可以是一個線性表
                ——下標個數又稱為數組的維度

2,順序存儲結構
①一維數組按下標順序分配即可
②多維數組:
(1):行優先,a00,a01,a02,a10,a11……
(2):列優先,a10,a20,a30,a11,a21……
3,應用:
①矩陣的壓縮存儲
——若aij==aji,則稱Anxn為矩陣
(1)對稱矩陣
——關于對角線對稱,這樣我們就只需要存儲上半角或者下半角的元素,就節約了一半
(2)三角矩陣
——下三角或者上三角全部為c(常數)或者0,c或0只用一個數組元素來存儲
(3)對角矩陣
——對角線附近有元素,其余元素全是0
(4)稀疏矩陣(非零元素遠大于0元素個數)
——使用三元組(橫坐標,縱坐標,值),運用數組行優先順序來保存為線性表
——三元組結構體:
typedef struct {
int row;
int col;
elementtype val;
}Triple;
——三元組順序表:
typedef struct {
int m;
int n;
int len;//非零元素總數
Triple data[Maxsize];
}TMatrix M;
①初始化
M->m = 0;M->n = 0;M->len = 0;
②創建一個稀疏矩陣
傳入稀疏矩陣的行,列值。賦值M->mM->n,輸入行列值,傳入M->data[k].row/col/val,每一次增加k的值,最后傳入M->k.
③輸出稀硫矩陣
……
④求轉置矩陣
先將M中的m,n,len賦值給t,再將每一個m里面的row col val賦值給t
⑤矩陣相加
先判斷行數,優先加行數小的,再判斷列數,優先加列數小的,若行列數都相等,則直接賦值data的三維坐標,val為n+m的val值總和。最后將mn的剩余數據按序賦值到t。
例如:void MatrixAdd(TMatrix* M , TMatrix* N, TMatrix* T)
{int i = 0,j = 0, k = 0;
elementtype v;
if(M->m!=N->m||M->n!=N->n)
{printf("矩陣不匹配");
exit(1)};
T->m = M->m;T->n = M->n;
while(ilen&&jlen)
{
if(M->data[i].rowdata[j].row)
{
T->data[k].row=M->data[i].row;
T->data[k].col=M->data[i].col;
T->data[k].val=M->data[i].val;
k++;
i++;
}
else if(M->data[i].row > N->data[j].row)
{
T->data[k].row=N->data[i].row;
T->data[k].col=N->data[i].col;
T->data[k].val=N->data[i].val;
k++;
j++;
}
else//行相等
{
if(M->data[i].col < N->data[j].col)
{
T->data[k].row=M->data[i].row;
T->data[k].col=M->data[i].col;
T->data[k].val=M->data[i].val;
k++;
i++;
}
else if(M->data[i].row > N->data[j].row)
{
T->data[k].row=N->data[i].row;
T->data[k].col=N->data[i].col;
T->data[k].val=N->data[i].val;
k++;
j++;
}
else//行列都相等
{
v = M->data[i].val + N->data[j].val;
T->data[k].row=M->data[i].row;
T->data[k].col=M->data[i].col;
T->data[k].val = v;
}
i++;
j++;
}
}
for(;ilen;i++)
{
T->data[k].row = M->data[i].row;
T->data[k].col = M->data[i].col;
T->data[k].val = M->data[i].val;
k++;
}

                                                     for(;ilen;i++)
                                                        {
                                                            T->data[k].row = M->data[j].row;
                                                            T->data[k].col = M->data[j].col;
                                                            T->data[k].val = M->data[j].val;
                                                            k++;
                                                        }
                                                      T->len = k;
                                                    }
                            ——————難點是行號的匹配問題,要進行行號的匹配

十,樹
1,基本術語
重要的概念:
①度,擁有的子樹個數
②葉子結點(分支結點):(非)終端節點的意思
③森林:互不相交的樹的集合
④深度:層次數
表示方法:樹形圖,文氏圖,廣義表,凹入表示法
2,二叉樹
——每個節點只有兩個子樹左子樹,右子樹,而且有序!左右子樹互換位置是兩種二叉樹
性質①二叉樹的第i層上有2^(i - 1)
性質②深度為k的二叉樹有2^k-1個結點
性質③葉子結點=結點數+1
兩種形態:
①滿二叉樹,即所有結點都有左子樹和右子樹
②完全二叉樹,左子樹有,右子樹不一定有,左子樹沒有,右子樹一定沒有。
(1)有n個結點的完全二叉樹深度為【log2n】+1
(2)
順序存儲結構
typedef int TElemType;
typedef TElemType SqBiTree【最大容納數】
SqBiTree bt;
按從左到右從上到下給完全二叉樹編號存入數組,沒有子樹的地方用0來表示。
鏈式存儲結構
typedef int TElemType;
typedef struct node {
TElemType data;
struct node * lchild, rchild;
}BiTnode,
BiTree;
(1)二叉鏈表存儲結構 lchild data rchild 三個結點域

            (2)三叉鏈表存儲結構 lchild data parent rchild 四個結點域
            (3)線索鏈表
             遍歷
            (1)先序遍歷(DLR)
                            1,遞歸實現
                                void x(BiTree bt) {
                                        if(bt) {
                                                visit(bt->data);
                                                x(bt->lchild);
                                                x(bt->rchild);
                                        }
                                }
                            2,非遞歸實現
                                void x(BiTree bt){
                                        Bitree stack【Maxsize】;//定義順序棧
                                        int top = -1;
                                        BiTree p = bt;
                                        while(p||top!=-1) {
                                                while(p) {
                                                        visit(p->data);//訪問結點數據
                                                        if(棧沒滿) {
                                                                top++; stack【top】 = p }
                                                         p = p->lchild;
                                                 }
                                                if(top!=-1){p=stack[top];  top--; p = p->rchild;}
                                 }
            (2)中序遍歷(LDR),改變visit函數的位置
            (3)后序遍歷(LRD),改變xisit函數的位置
                            ——便利操作是非線性結構線性化
                            ——訪問根結點和遍歷其左右子樹的順序不同,每一次遍歷每個結點需要經過三次,“先后序”遍歷只是在這三次的那一次訪問結點元素的區別
            (4)層次遍歷
                            利用順序隊列數據結構

              二,二叉樹的線索化。
            三,樹和森林
                    1,雙親表示法, typedef char TElemType;
                                                typedef struct PTnode {
                                                        TElemType data;
                                                        int parent;
                                                }PTNode;
                                                typedef struct {
                                                        PTNode node【】;
                                                        int r,n;
                                                }
                    2,孩子表示法,typedef struct CTNode {
                                                    int child;
                                                    struct CTNode * next;
                                                } * ChildPtr;
                                                typedef struct CTNode {
                                                    TElemType data;
                                                    ChildPtr FirstChild;
                                                }CTBox;
                                                typedef struct {
                                                   CTBox nodes【】;
                                                    int r, n; 
                                                }CTree;
                    3,也可以綜合以上兩種制造雙親孩子鏈表,不做解釋
                    4,兄弟孩子表示法
                            (與二叉樹的表示方法差不多,顧已成為二叉樹表示法)
                                                typedef char TElemType;
                                                    typedef struct CSNode {
                                                            TElemType data;
                                                            struct CSNode *firstchild * nextsibling;
                                                    }CSNode, * CSTree;

                三,
                    1,樹與二叉樹的轉換
                            1,因為樹的兄弟孩子表示法,顧給定一棵樹,可以找到唯一的一顆二叉樹與之對應
                                    1,樹轉換為二叉樹
                                            ①凡是下一個兄弟,用線連起來(加線);
                                            ②去掉每個結點除第一個孩子之外與孩子的連線(抹線)
                                            ③排列(調整)
                                     2,二叉樹轉化為樹
                                            ①若結點是雙親的左孩子,則把該結點的右結點,右結點的右結…都與雙親連起來(加線)
                                            ②抹去所有雙親結點與右孩子的連線(抹線)
                                            ③排列(調整)
                                    ——這樣轉換得到二叉樹和普通樹唯一對應
                    2,森林與二叉樹的轉換
                            1,森林轉換為二叉樹
                                將森林中的每一棵樹轉為二叉樹(轉換),將每一個二叉樹的根節點連線(加線),然后調整
                            2,二叉樹轉換為森林
                                抹去二叉樹根節點右鏈與其所有右鏈上的右結點連線(抹線),將二叉樹轉換為樹(轉換),調整                 
                    3,樹和森林的遍歷

四,二叉樹的應用

最后,圖
一 重要定義。
1.弧或邊帶權的圖稱為有向網或無向網
2.如果無向圖中任意一對頂點都是連通的,就成為連通圖
3.如果有向圖中,對于每一對頂點vi和vj都存再一條vi到vj的路徑以及vj到vi的路徑,就成為強連通圖
4.度表示和頂點關聯的邊的數目,有向圖存在出度和入度,顧名思義
5.路徑上經過邊的數目稱為路徑長度,除頂點和終點可以相同外,其余各點不同稱為簡單路徑,若起點和終點相同稱為環或回路。

二 存儲結構。
1.鄰接矩陣
(1)無向圖的鄰接矩陣通常是對稱的,有向則不是,因為(vi,vj)與(vj,vi)的不同
(2)便于查找任意邊或邊上的權
——查找圖中是否有邊(vi,vj)查找第i行第j列上的元素是否為有效數
(3)便于查找任一頂點的度
——對無向圖,vi的度是第i行或第i列上的有效元素個數
——對有向圖,vi的出度就是第i行的有效元素的個數,入度就是第i列上的有效元素個數
typedef int V;
typedef struct {
int A【】【】//鄰接矩陣存儲頂點間的鄰接關系
V v【】//存儲頂點的表
int vex,arc//圖的頂點數和弧數
}MGraph;
(4)缺點!!:存儲空間的浪費,無論有多少條邊總是需要開銷nXn空間
2.鄰接表
(1)保存有向圖中,把保存出邊的叫鄰接表,保存入邊的叫逆鄰接表,需要占用
n+e個存儲空間
(2)找一個頂點的邊或者鄰接點,從頂點表中取出對應的表頭指針,從表頭指針開始查找即可
typedef int V;
typedef struct ArcNode{//定義邊表結點
int adjvex;//該弧指向頂點的位置
struct ArcNode * nextarc;//指向下一條弧的指針
int info;//該弧上的權值
}ArcNode;
typedef struct VNode {
Vertex data;
ArcNode *firstarc; //指向邊表
}VNode;
typedef struct {
VNode adjlist【】;
int vexnum, arcnum//頂點數,弧數
}
3.鄰接多重表
頂點表還是由data值域存放的頂點加上firstedge指針域存放的
4.十字鏈表

三 圖的遍歷
1.深度優先搜索
從一個頂點開始,先訪問一個頂點的鄰接頂點,依次下去,直到沒有沒訪問的鄰接頂點的鄰接頂點,就倒回去,直到有沒被訪問的鄰接頂點的那個節點再訪問其沒被訪問的鄰接頂點
(1)采用visited數組表示頂點是否已經被訪問
(2)采用鄰接表的存儲方式表示圖,整個算法分DFS和DFST
2.廣度優先搜索
從一個頂點開始先訪問一個頂點所有的鄰接頂點,然后按照順序依次訪問剛訪問那一組鄰接頂點的鄰接頂點,就像一個樹一樣
(1)也需要一個訪問標志visited數組
(2)需要設置一個隊列Queue來記錄已被訪問的頂點順序
(3)采用鄰接表的存儲方式表示圖,整個算法分BFS和BFST

四 最小生成樹
對于網絡來說,弧一般都是帶權的,,對于一個連通圖G,其最小生成樹指的是包括其所有頂點,以及部分邊,滿足邊權總和最小,圖是連通的這樣一個。
1.普里姆算法

            2.克魯斯卡爾算法

五 DAG有向無環圖
1.拓撲排序
通常把用頂點表示活動,弧表示活動間先后順序的有向圖稱為頂點的網——AOV網
在AOV網中,若不存在回路,則所有頂點都可以排成一個序列,所有前驅活動都排在后驅活動的前面,這叫拓撲序列,由AOV網構造拓撲序列的過程叫做拓撲排序
方法:(1)在AOV網中選擇一個入度為0的點把它寫入拓撲序列中
(2)在AOV網中刪除該點以及其所有的出邊
結果:(1)網中全部頂點被輸出,說明網中不存在回路(2)頂點未被全部輸出,且網中不存在入度為0的頂點,說明有回路
采用鄰接表作為有向圖的存儲結構,需要設置一個一維整型數組,用來保存圖中每個頂點的入度值
算法:(1)將入度為0的頂點入棧
(2)從堆棧中彈出棧頂元素:
①輸出棧頂元素
②把該頂點發出的所有有向邊刪去,即將所有后繼頂點的入度減1,若減1后該頂點入度為0,則該頂點入棧
③重復②直到沒有入度為0的頂點
實現:
2.關鍵路徑

六 最短路徑
1,.某一源頭到各定點
2.每一對頂點之間

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 第一章 緒論 什么是數據結構? 數據結構的定義:數據結構是相互之間存在一種或多種特定關系的數據元素的集合。 第二章...
    SeanCheney閱讀 5,822評論 0 19
  • 一、數據結構緒論 邏輯結構與物理結構邏輯結構:集合、線性(一對一)、樹(一對多)、圖(多對多)物理結構:順序存儲結...
    scarqin閱讀 2,565評論 0 3
  • 上一篇文章程序員面試闖關(一):字符串匹配+排序+查找列舉說明了各種常見的排序算法等算法基礎,這里,主要分析下數據...
    androidjp閱讀 1,608評論 0 26
  • 因為之前就復習完數據結構了,所以為了保持記憶,整理了一份復習綱要,復習的時候可以看著綱要想具體內容。 樹 樹的基本...
    牛富貴兒閱讀 7,010評論 3 10
  • 好喜歡李白啊。“喝”的那一聲真好聽,整首歌兒就等著聽這一句。就是喜歡這種吊兒郎當天不怕地不怕,天塌下來也不管我事的...
    Maya3319閱讀 426評論 0 1