1. 程式人生 > >`輕鬆搞定資料結構(線性表篇)

`輕鬆搞定資料結構(線性表篇)

資料結構(線性表)

相關的C/C++基礎知識

  • typedef 語句的使用
 //①宣告一個結構體,或者為 一個型別修改名字方便理解。
    typedef struct xxx{
        int xxxx;
     }newName;
 //②把int 變數名 改為NewInt型
     typedef int NewInt;
  • ElemType的定義和使用(DataType的定義和使用)
    /*可表示任意一種基本型別
     比如: typedef int ElemType
     */
     //可以模板函式的型別引數 解決該問題
     template
<typename T> void opooc(T t){ cout<<t; }
  • new和delete的使用(malloc()和free()的使用)
/*
動態new一個含100個int型別大小的地址
int  *p = new int[100];
p指向第一個元素的地址
使用完一定要刪除 delete []p; 
如果只有一個元素則可以delete p;
在類中呼叫的時候要把new函式放在建構函式裡,把delete放在解構函式中
例如:
*/
    class opooc{
    public:
        opooc();
        ~opooc();
        int *p;
    };
    opooc
::opooc(){ p = new int[10]; cout<<"created"<<endl; } opooc::~opooc(){ delete []p; cout<<"deleted"<<endl; } /* c語言中 使用 malloc開闢空間,使用free釋放空間 int *p = (int *)malloc( 100); free p; 其中第一個括號放 空間地址存放元素的型別,第二個括號必須填位元組數 sizeof()可以計算型別的大小,如果要計算陣列的大小的時候,一定記得要傳陣列,不要傳陣列的指標。 如果要使用形引數組的長度,一定要在每次傳參的時候傳值。 或者把資料包裝成一個結構,結構中有一個欄位是長度,另外一個欄位是資料內容 */ /* 程式碼在系統的中的心路歷程: https
://www.cnblogs.com/kekec/p/3238741.html 原始檔-> 預處理[主要是做一些程式碼文字的替換工作。(該替換是一個遞迴逐層展開的過程。)]-> 編譯(詞法分析(lex)、語法分析(yacc)、語義分析及優化,優化,生成彙編程式碼)-> 彙編(彙編程式碼->機器指令。)-> 連結(這裡講的連結,嚴格說應該叫靜態連結。多個目標檔案、庫->最終的可執行檔案(拼合的過程)。分配靜態儲存空間到棧) 執行(分配動態空間到堆) */
  • 元素的位序和元素的儲存下標

位序是使用者看的,元素的儲存下標是計算機採用的;
不同語言不一樣,python 可以給定陣列的下表範圍(比如-100 到 xx)

  • 函式的返回值及型別Status的定義
    status提高可讀性
//自定義throw丟擲異常
class PerException{
public:
    PerException(string str);
};
PerException::PerException(string str){
    try {
        throw str.c_str();
    } catch (const char* e) {
        cout<<e;
        exit(0);
    }
}
  • 常量的定義(MAXSIZE等)和使用
#define X 100
const int x = 100;
//注意:使用define定義不能加分號
  • 引用呼叫引數的定義和使用
//m 對應了傳入的引數,不分配記憶體
void test(int &m){
    m++;
}
  • 資料結構中一些常用變數的定義問題

迴圈控制變數i,j,k等,指標變數p,q,r等

線性表的型別定義

  • 型別定義

線性表是由零個或者多個數據元素組成的有序的序列。
線性表的儲存包括順序儲存和鏈式儲存

  • 相關的基本操作:
//初始化
void initList(T &L)
//清空
void clearList(T &L)
//插入
bool insert(T &L,int local,int data)
//刪除
int deleteSeq(T &L, int local)
//定位
int locate(T L,int res)
//取第i個元素:
int getIndexOf(T L,int local)
//求表的長度:
int length(T L)

線性表的順序儲存結構

//順序儲存結構
typedef struct {
    int arr[MAXSIZE];
    int length;
}SeqList;

//初始化
void initList(SeqList &L){
    for (int i = 0; i<MAXSIZE; i++) {
        L.arr[i] = 0;
    }

    L.length =0;
}
//清空
void clearList(SeqList &L){
    for (int i = 0; i<MAXSIZE; i++) {
        L.arr[i] = 0;
    }
    L.length = 0;
}
//插入
bool insert(SeqList &L,int local,int data){
    if (L.length == MAXSIZE) {
        PerException("the length of L is more than MAXSIZE");
    }
    if (local<0||local>L.length) {
        PerException("the local is less than 0 or  it is  greater than length");
    }
    // length =5
    // 01234
    for (int i = L.length; i > local; i--) {
        L.arr[i] = L.arr[i-1];
    }
    L.arr[local] = data;
    L.length++;
    for (int i = 0 ; i < L.length; i++) {
        cout << L.arr[i]<<" ";
    }
    cout << endl;
    return true;
}
//刪除
int deleteSeq(SeqList &L, int local){
    if (L.length == 0) {
        PerException("the length of L is 0");
    }
    if(local < 0|| local>=L.length){
        PerException("the local is less than 0 or  it is equal or greater than length");
    }
    int res = L.arr[local];
    for (int i=local+1; i<L.length; i++) {
        L.arr[i-1] = L.arr[i];
    }
    L.arr[L.length-1] =0;
    L.length--;
    return res;
}
//定位
int locate(SeqList L,int res){
    int local =-1;
    for(int i=0;i<res;i++){
        local = L.arr[i]==res?i:local;
    }
    //返回-1說明沒有該元素
    return local;
}
//取第i個元素:
int getIndexOf(SeqList L,int local){
    if (local < 0||local>=L.length) {
        PerException("the local is less than 0 or it is equal or greater than length");
    }
    return L.arr[local];
}
//求表的長度:int length(L)
int length(SeqList L){
    return L.length;
}
// 測試
int main(){
    SeqList l;
    initList(l);
    insert(l, 0, 46);
    insert(l, 1, 32);
    insert(l, 2, 52);
    insert(l, 3, 62);
    insert(l, 4, 82);
    for (int i = 0 ; i < l.length; i++) {
        cout << l.arr[i]<<" ";
    }
    cout<<endl;

    deleteSeq(l,2);
    for (int i = 0 ; i < l.length; i++) {
        cout << l.arr[i]<<" ";
    }
    cout << endl;
    deleteSeq(l,3);
    for (int i = 0 ; i < l.length; i++) {
        cout << l.arr[i]<<" ";
    }
    cout << endl;
    return 0;
}

線性錶鏈式儲存結構(帶表頭結點)

//定義
(1)typedef struct  LNode{
    int data;
    LNode* next;
}LNode,* LinkList;
//初始化
void initList(LinkList  &L){
    LNode* p = new LNode;
    p->next =nullptr;
    L =p;
};

//清空
void clearList(LinkList& L){
    LNode *p  = L->next;
    L->next = nullptr;
    while (p != nullptr) {
        LNode* q = p;
        p = p->next;
        delete q;
    }
}
//插入
//local以0位基點,頭結點位置為-1
bool insert(LinkList& L ,int local,int x){
    if (local < 0) {
        PerException(" the local is less than 0");
    }
    LNode* p = L;
    int count = -1;
    while (p != nullptr && count < local-1) {
        p = p->next;
        count++;
    }
    if (p == nullptr) {
        PerException("the local is more than size");
    }else{
        LNode* q = new LNode;
        q->next = p->next;
        q->data = x;
        p->next = q;
    }
    return true;
}
//刪除
int deleteLNode(LinkList& L,int local){
    if (local<0) {
        PerException("");
    }
    //初始化要返回的值
    int data = 0;
    int count = -1;
    LNode* p = L;
    while (p != nullptr && count <local -1) {
        p = p->next;
        count++;
    }
    if (p == nullptr || p ->next ==nullptr) {
        PerException("");
    }else{
        LNode* q = p -> next;
        data = q->data;
        p->next = q->next;
        delete q;
    }
    return data;
}
//定位
int locate(LinkList L ,int data){
    //指向L作為頭結點的next
    LNode* p = L->next;
    int count = 0;
    while (p!= nullptr && p->data != data) {
        p = p->next;
        count++;
    }
    if(p == nullptr ){
        PerException("");
    }
    return count;
}

//取第i個元素
int getIndexOf(LinkList L ,int local){
    LNode* p =L;
    int count =-1;
    int data = 0;
    while (p != nullptr && count < local) {
        p = p->next;
        count++;
    }
    if (p == nullptr) {
        PerException("");
    }else{
        data = p->data;
    }
    return data;
}
//求鏈長
int length(LinkList L){
    int count = 0;
    LNode* p = L->next;
    while (p != nullptr) {
        count++;
        p = p->next;
    }
    return count;
}
//列印順序鏈
void printLinkList(LinkList L){
    LNode* p =L->next;
    while (p != nullptr ) {
        cout<<p->data<<" " ;
        p= p->next;
    }
    cout<<endl;
}
//測試資料
int main(){
    LinkList L;
    initList(L);
    insert(L, 0, 24);
    insert(L, 1, 35);
    insert(L, 2, 37);
    insert(L, 3, 88);
    insert(L, 4, 31);
    insert(L, 5, 23);
    printLinkList(L);
    deleteLNode(L, 3);
    printLinkList(L);
    deleteLNode(L, 1);
    printLinkList(L);
    cout<<getIndexOf(L, 3)<<endl;
    cout<<length(L)<<endl;
    cout<<locate(L, 23)<<endl;
    clearList(L);
    printLinkList(L);
    return 0;
}

順序儲存和鏈式儲存的比較

  1. 儲存空間的連續性?
    鏈式儲存是動態儲存空間分配,儲存空間不具有連續性
    順序儲存靜態儲存空間分配,儲存空間具有連續性

  2. 隨機存取否?
    隨機存取就是直接存取,可以通過下標直接訪問的那種資料結構,與儲存位置無關,順序儲存。
    非隨機存取就是順序存取了,不能通過下標訪問了,只能按照儲存順序存取,與儲存位置有關,鏈式儲存。

  3. 插入/刪除操作的效率?
    順序儲存的效率低 (需要遍歷)
    鏈式儲存的效率高 (直接找位置)

  4. 有無附加的儲存空間?
    順序表沒有附加儲存空間;
    單鏈表有附加儲存空間;

  5. 那種資料結構更好?(空間 時間)
    但是不能籠統的說那種資料結構更好。
    作為一般規律,當線性表中元素個數變化較大或者未知時,最好使用連結串列;
    如果實現知道線性表的大致長度,使用順序表的空間效率會高;
    但是還要考慮到時間效率,如果經常插入刪除,還是首先考慮鏈式儲存結構。

迴圈連結串列

  • 定義

形如:A→B→C→D→A

  • 結構體
 typedef struct LNode
{   int data;
    LNode * next;
}CLNode, * CLinkList;
  • 實現插入操作
//實現插入(帶表頭結點)
bool insert(CLinkList& L, int i, int x)
{
    int j=-1;
    LNode *p=L; 
    while (p->next!=L &&j<i-1){
        p=p->next;
        j++;
    }
    if ( j < i-1 )
        return -1;  
    //只要j==i-1, 無論p->next是否等於L都是可以插入的
    LNode* q = new LNode;
    q->data=x;
    q->next=p->next;
    p->next=q;
    return 1;
}

初始化迴圈列表:讓first指標的next指向first;
插入:讓p節點指向first,迴圈遍歷到要插入的位置Local的上一個結點,操作和單鏈表一樣,只不過在迴圈的時候控制停止的時候,
要判斷p的next是否為first。也可以用雙指標。也要考慮,插入的位置是否越界。
刪除:同插入,再不過判斷結束時,判斷next是否為first

雙向連結串列

  • 定義

形如: A←→B←→C←→D

  • 結構體
typedef struct DNode
{   int data;
    DNode *prior;
    DNode *next;
} DNode, *DLinkList;
  • 實現(帶表頭結點)

    p指向一個結點:

    • 如何在p前面(後面)插入一個q結點?

    前面插入:
    q->next = p->prior->next
    p->prior->next = q
    q->prior = p->prior
    p->prior =q
    後面插入:
    q->next = p->next
    p->next = q
    q->prior = p->next->prior
    p->next->prior = q

  • 如何刪除p後面(前面)的結點q?

    刪除前面:
    q= p->prior
    q->prior->next=p
    p->prior = q->prior
    delete q
    刪除後面:
    q=p->next
    q->next->prior = p
    p->next = q->next
    delete q

  • 如何刪除p指向的結點?

    p->prior->next =p->next
    p->next->prior =p->prior
    delete p

線性表的應用

相關推薦

`輕鬆資料結構線性

資料結構(線性表) 相關的C/C++基礎知識 typedef 語句的使用 //①宣告一個結構體,或者為 一個型別修改名字方便理解。 typedef struct xxx{ int xxxx; }newN

Mr.J--C語言頭函式的建立附嚴薇敏《資料結構線性程式碼

  如何正確編寫 C 語言標頭檔案和與之相關聯的 c 源程式檔案 檢視此文章需要有一定的C語言程式設計基礎 首先就要了解它們的各自功能。要理解C 檔案與標頭檔案(即.h)有什麼 不同之處,首先需要弄明白編譯器的工作過程。 一般說來編譯器會做以下幾個過程: 1.預處理階段 2

資料結構線性

線性結構-線性表 實驗簡介 資料結構中的邏輯結構分為線性結構和非線性結構,這一章和下一章我們會介紹線性結構,簡單地說,線性結構是n個數據元素的有序(次序)集合,它有下列幾個特徵: 1.集合中必存在唯一的一個"第一個元素"; 2.集合中必存在唯一的一個"最後的元素

一起來學SpringBoot | 第十九輕鬆資料驗證

SpringBoot是為了簡化Spring應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 對於任何一個

轉載一文資料倉庫之拉鍊,流水錶,全量,增量

轉載自:https://blog.csdn.net/mtj66/article/details/78019370 全量表:每天的所有的最新狀態的資料, 增量表:每天的新增資料,增量資料是上次匯出之後的新資料。 拉鍊表:維護歷史狀態,以及最新狀態資料的一種

資料結構2--線性java程式碼實現線性的鏈式儲存

1.鏈式儲存       2.分析       每個節點為一個物件,該物件包含資料域和指標域        整條單鏈表為一個物件,他和節點物件進行組合。  3.

資料結構1--線性java程式碼實現線性的順序儲存

1.資料結構的概念      資料:資訊載體,計算機處理的物件的總稱      資料元素:也稱結點,組成資料的基本單位      資料項:資料項是資料的最小單位     &n

資料結構c語言版線性的單鏈儲存結構

本文轉自:https://blog.csdn.net/prlhnxx/article/details/79174782 /* run this program using the console pauser or add your own getch, system("pause") or i

資料結構系列--線性,順序儲存結構

線性表定義 線性表(List):零個或多個數據元素的有限序列。 注意:是一個序列,每個元素之間是有序的,第一個元素無先驅,最後一個元素無後繼 數學定義: 若將線性表記為:(a1,a2,...,ai-1,ai,ai+1...,an),則ai-1領先於ai,ai+1領先於

資料結構線性結構線性、棧與佇列

3.3 線性表的抽象資料型別ADT 線性表的抽象定義 集合A和集合B的並集操作 3.4 線性表的順序儲存結構 線性表的順序儲存的結構程式碼 地址計算 3.5 順序儲存結構的插入與刪除 獲得元素操作 GetElem 插入操作 ListInsert 刪除

用C語言實現線性歸併_含原始碼和執行結果_資料結構C語言版

採用動態分配順序儲存結構實現 採用單鏈表結構實現 1.採用動態分配實現 #include<stdio.h> #include<stdlib.h> #define LIST_INIT_SIZE 100 #define LISTINCREM

資料結構線性

資料結構之線性表一主要講的是線性表的順序儲存結構和鏈式儲存結構的實現和程式碼。這次我們來討論下靜態連結串列,迴圈連結串列和雙向連結串列。 靜態連結串列 我們讓陣列每個元素都是由兩個資料域組成:data和cur。資料域data用來儲存資料元素,cur相當於我們連結串列中的n

Springboot212輕鬆資料驗證

原始碼地址 對於任何一個應用而言,客戶端做的資料有效性驗證都不是安全有效的,而資料驗證又是一個企業級專案架構上最為基礎的功能模組,這時候就要求我們在服務端接收到資料的時候也對資料的有效性進行驗證。為什麼這麼說呢?往往我們在編寫程式的時候都會感覺後臺的驗證無關緊要

資料結構(1) 線性技巧及應用:字首和、排序逆序對求法之一

雖然線性表實在過於簡單,幾乎不會有大佬寫它的應用 但是作為一個菜雞的我還是打算歸納總結一下線性表一些應用和技巧 1.字首和 emmmm 我們來看這樣一個問題 已知一個序列s[ i ] (1<=i<=n),有m個請求,每個請求為兩個整數a,b(1<=a<=b&l

資料結構線性 -- 連結串列總括

今天來總結一下連結串列。  首先,   什麼是連結串列?     就是採去鏈式儲存結構的線性表,所謂鏈式儲存就好比火車的車廂一樣,一節一節的連線起來,成為一個線性表。這種方式採用動態儲存分配方式,即

資料結構線性順序,單鏈,迴圈連結串列,雙向連結串列-- 圖書管理系統

順序表 #include <iostream> #include <cstring> #include <cstdlib>///exit()標頭檔案exit(0):正常執行程式並退出程式。exit(1):非正常執行導致退出程式 #incl

基於C/C++語言資料結構線性

資料結構學習筆記: 資料結構的重要性:資料結構我感覺很重要,不僅僅是考試很重要,而且在以後程式設計師事業上都是尤為重要的,知乎上有網友評價資料結構是最重要的程式設計基本能力,沒有之一。我感覺這個說法很對,並且大家都知道,資料結構與演算法這種說法常常被大家使用,就是因為資料

演算法與資料結構--實現線性的合併操作合併後按非遞減排列

/*檔名稱:實現線性表的合併操作(合併後按非遞減排列)*/#include <bits/stdc++.h> using namespace std; #define LIST_INIT_SIZE 100 //線性表儲存空間的初始分配量

資料結構線性的鏈式儲存實現附完整程式碼

順序表插入、刪除時需要通過移動資料來實現,影響了執行效率。 而連結串列不要求邏輯上相鄰的兩個資料元素物理上也相鄰,因此對線性表的插入、刪除不需要移動資料元素,只需要修改鏈。 下面介紹帶頭結點的鏈式表: 資料結構: typedef int ElementType; ty

Java數據結構線性-->順序簡單實現

str out ret rgs sem emp 效果 tab 廣泛 線性表是一種可以在任意位置插入和刪除元素,由n個同類型元素組成的線性結構。主要包括順序表,單鏈表,循環單鏈表,雙向鏈表和仿真鏈表。應用比較廣泛的是順序表和單鏈表。 2 下面是線性表的接口,主要操作包括