DataStructure_第二章 線性表 ( 單鏈表 / 循環鏈表 / 雙向鏈表 及 靜態鏈表 的分析及其實現 )









0x0000 線性表的概念及抽象數據類型定義

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述













0x0001 線性表的順序存儲

在這裏插入圖片描述

在這裏插入圖片描述













0x0010 線性表的鏈式存儲



1. 單鏈表

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

親自調試了一遍, 問題已經修改, 如果還有bug歡迎路過的大佬指正!

/*** 
 * @Author      : acmaker
 * @Date        : 2020-03-10 11:33:03
 * @LastEditTime: 2020-03-16 14:14:51
 * @FilePath    : \myCPlusPlusCode\DataStructure\LinearList\SingalLinkedList.cpp
 * @Website     : http://csdn.acmaker.vip
 * @Description : 
 */



#include <bits/stdc++.h> 
using namespace std; 
#define rg register 
#define sc scanf 
#define pf printf 
typedef long long ll; 

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0

// 線性表的鏈式存儲結構
typedef char ElemType;
typedef struct Node {
    ElemType data;
    Node* next;
}Node, *LinkedList;
LinkedList L;

long long ListLength ( LinkedList L );
void InitList ( LinkedList *L );
void CreateFromHead ( LinkedList L );
void CreateFromTail ( LinkedList L );
Node* Get ( LinkedList L, long long pos );
Node* Locate ( LinkedList L, ElemType key );
int InsList ( LinkedList L, int pos, ElemType e );
int DelList ( LinkedList L, int pos, ElemType *e );
void DestroyList ( LinkedList L );
void reverseList ( LinkedList );


int main ( ) {  // freopen( "F:\\in\\.txt" , "r" , stdin ); 

    InitList( &L );

    // CreateFromHead( L );

    CreateFromTail( L );

    cout << Get( L, 3 )->data << endl;

    cout << Get( L, 2 )->data << endl;

    cout <<  Locate( L, '3' ) << endl;

    cout << InsList( L, 1, '8' ) << endl;

    ElemType backup;
    cout << DelList( L, 1, &backup ) << endl;

    DestroyList( L );
    

    return 0 ; 
} 

// 代碼實現.

/***
 * @description: 計算帶頭結點的單鏈表 長度
 * @param :
 * @return:
 */
long long ListLength ( LinkedList L ) {
    Node *p = L->next;
    long long i;
    for ( i = 0; p!=NULL; ++i ) {
        p = p->next;
    }
    return i;
}

/*** 
 * @description: 初始化頭結點, 注意傳遞的參數是頭指針!
 * @param : 
 * @return: 
 */
void InitList ( LinkedList *t ) { 
    *t = (LinkedList)malloc( sizeof(Node) );
    (*t)->next = NULL;
}

/*** 
 * @description: 頭插法建表
 * @param : 
 * @return: 
 */
void CreateFromHead ( LinkedList L ) {
    Node *s;
    bool state = true; // false爲輸入結束
    ElemType input;
    while ( state ) {
        cin >> input;
        if ( input=='$' ) state = false;
        else {
            s = (Node*)malloc( sizeof(Node) );
            s->data = input;
            s->next = L->next;
            L->next = s;
        }
    }
}

/*** 
 * @description: 尾插法建表
 * @param : 
 * @return: 
 */
void CreateFromTail ( LinkedList L ) {
    Node *s, *r = L;
    bool state = true;
    ElemType input;
    while ( state ) {
        cin >> input;
        if ( input=='$' ) state = false, r->next = NULL;
        else {
            s = (Node*)malloc( sizeof(Node) );
            s->data = input;
            r->next = s;
            r = s;
        }
    }
}

/*** 
 * @description: 帶頭結點單鏈表查找第 i 個結點
 * @param : 
 * @return: 
 */
Node* Get ( LinkedList L, long long pos ) {
    Node* p = L;
    long long i = 0;
    for ( ; (p->next!=NULL)&&(i<pos); ++i ) {
        p = p->next;
    }
    return (i==pos ? p : NULL);
}

/*** 
 * @description: 帶頭結點的單鏈表 查找值爲key的結點
 * @param : 
 * @return: 返回查找到的值的地址...貌似沒啥用...
 */
Node* Locate ( LinkedList L, ElemType key ) {
    Node* p = L->next;
    for ( ; p!=NULL; p=p->next ) {
        if ( p->data==key ) break;
    }
    return p;
}

/*** 
 * @description: 帶頭結點的單鏈表 插入
 * @param : 
 * @return: 
 */
int InsList ( LinkedList L, int pos, ElemType e ) {
    if ( pos<=0 ) return ERROR;
    Node *pre = L;
    for ( long long i = 0; (pre!=NULL)&&(i<pos-1); ++i ) {
        pre = pre->next;
    }
    if ( pre==NULL ) {
        cout << "超出鏈表最大長度!" << endl;
        return ERROR;
    }
    Node *s = (Node*)malloc( sizeof(Node) );
    s->data = e;
    s->next = pre->next;
    pre->next = s;
    return OK;
}

/*** 
 * @description: 帶頭結點的單鏈表 刪除一個元素
 * @param : 注意, ElemType參數需要傳遞引用!
 * @return: 
 */
int DelList ( LinkedList L, int pos, ElemType *e ) {
    if ( pos<0 ) return ERROR;
    Node *pre = L; // 注意刪除的時候從頭結點開始算
    for ( long long i = 0; (pre->next!=NULL)&&(i<pos-1); ++i ) {
        pre = pre->next;
    }
    if ( pre->next==NULL ) {
        cout << "超出鏈表最大長度!" << endl;
        return ERROR;
    }
    Node *t = pre->next;
    pre->next = t->next;
    *e = t->data;
    free(t);
    return OK;
}

/*** 
 * @description: 銷燬單鏈表
 * @param : 
 * @return: 
 */
void DestroyList ( LinkedList L ) { 
    Node *p = L, *t;
    while ( p->next!=NULL ) { 
        t = p->next;
        free(p);
        p = t;
    }
}

/*** 
 * @description: 逆置單鏈表( 使用頭插法 )
 * @param : 
 * @return: 
 */
void reverseList( LinkedList L ) {
    Node *p = L->next;
    L->next = NULL;
    for ( ; p!=NULL; p=q ) {
        q = p->next;
        p->next = L->next;
        L->next = p;
    }
}

計算相關

在長度爲N的順序表仲,插入一個新元素平均需要移動表中_______個元素?刪除一個元素平均需要移動_______個
在長度爲N的順序表仲,插入一個新元素平均需要移動表中________個元素,刪除一個元素平均需要移動_______個元素,

- 在表頭操作需要移動幾個 在表尾操作需要移動幾個 一共需要移動幾個 平均需要移動幾個
插入 n 0 n/2 n/2 / (n+1)
刪除 n-1 0 (n-1)/2 (n-1)/2 / n



2. 循環鏈表

在這裏插入圖片描述

循環鏈表的建表, 增刪改查 無非就是把最後尾指針指向表頭罷了, 不重複了

以下是合併兩個單鏈表爲 循環鏈表 的代碼, 待測試…

/*** 
 * @Author      : acmaker
 * @Date        : 2020-03-16 09:42:12
 * @LastEditTime: 2020-03-16 10:22:15
 * @FilePath    : \myCPlusPlusCode\DataStructure\LinearList\CircleLinkedList.cpp
 * @Website     : http://csdn.acmaker.vip
 * @Description : 
 */


#include <bits/stdc++.h> 
#include "SingalLinkedList.cpp"
using namespace std; 
#define rg register 
#define sc scanf 
#define pf printf 
typedef long long ll; 

typedef char ElemType;
typedef struct CNode {
    ElemType data;
    CNode* next;
}CNode, *CircleLinkedList;

/*** 
 * @description: 傳入兩個單鏈表的表頭, 合併爲 循環鏈表
 * @param : 
 * @return: 
 */
CircleLinkedList merge_1 ( CircleLinkedList LA, CircleLinkedList LB ) {
    CNode *pa, *pb;
    while ( pa->next!=NULL ) pa->next;
    while ( pb->next!=NULL ) pb->next;
    pa->next = LB->next;
    free( LB );
    pb->next = LA;
    return LA;
}


/*** 
 * @description: 傳入兩個單鏈表的表尾, 合併爲 循環鏈表
 * @param : 
 * @return: 
 */
CircleLinkedList merge_2 ( CircleLinkedList RA, CircleLinkedList RB ) {
    CNode *t = RA;
    RA->next = RB->next->next;
    free( RB->next );
    RB->next = t->next;
    return RB; // 返回新的表尾
}



int main ( ) {  // freopen( "F:\\in\\.txt" , "r" , stdin ); 

    




    return 0 ; 
} 



3. 雙向鏈表

插入操作
在這裏插入圖片描述

刪除操作

在這裏插入圖片描述

雙向鏈表就是多了了前驅指針, 增刪改查的時候能靈活些, 注意掛鏈都是先操作前驅的

代碼待驗證…

/*** 
 * @Author      : acmaker
 * @Date        : 2020-03-16 10:11:31
 * @LastEditTime: 2020-03-16 11:26:05
 * @FilePath    : \myCPlusPlusCode\DataStructure\LinearList\DoubleLinkedList.cpp
 * @Website     : http://csdn.acmaker.vip
 * @Description : 
 */


#include <bits/stdc++.h> 
#include "SingalLinkedList.cpp"
using namespace std; 
#define rg register 
#define sc scanf 
#define pf printf 
typedef long long ll; 

#define OK 1
#define Error 0

typedef char ElmeType;
typedef struct { 
    ElmeType data;
    DNode *prior, *next;
}DNode, *DoubleLinkedList;

int InsPrior ( DoubleLinkedList L, int pos, ElemType e ) {
    if ( pos<0 ) return ERROR;
    DNode *p = L->next;
    for ( long long i = 0; (p!=NULL)&&(i<pos); ++i ) {
        p = p->next;
    }
    if ( p==NULL ) {
        cout << "超出鏈表最大長度!" << endl;
        return ERROR;
    }
    DNode *s = (DNode*)malloc( sizeof(DNode) );
    s->data = e;
    s->prior = p->prior;
    p->prior->next = s;
    s->next = p;
    p->prior = s->next;
    return OK;
}

int Del ( DoubleLinkedList L, int pos, ElemType *e ) {
    if ( pos<0 ) return ERROR;
    DNode *p = L;
    for ( long long i = 0; (p!=NULL)&&(i<pos); ++i ) {
        p = p->next;
    }
    if ( p==NULL ) {
        cout << "超出鏈表最大長度!" << endl;
        return ERROR;
    }
    *e = p->data;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    free( p );
    return OK;
}

int main ( ) {  // freopen( "F:\\in\\.txt" , "r" , stdin ); 

    




    return 0 ; 
} 



** 靜態鏈表

待填坑…









0x0011 線性表應用



1.> 單鏈表的置換

其實就是頭插法建表的思想, 重複執行着 當前節點 指向 上一個節點, 直到表尾.

在這裏插入圖片描述

/*** 
 * @description: 逆置單鏈表( 使用頭插法 )
 * @param : 
 * @return: 
 */
void reverseList( LinkedList L ) {
    Node *p = L->next, *q;
    L->next = NULL;
    for ( ; p!=NULL; p=q ) {
        q = p->next;
        p->next = L->next;
        L->next = p;
    }
}



2.> 一元二次多項式的相加









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章