數據結構的基本概念 單鏈表的應用

什麼是數據結構 ?

答:1.數據結構是計算機存儲、組織組織的方式。數據結構是指相互之間存在一種或多種特定關係的數據元素的集合。通常情況下,精心選擇的數據結構可以帶來更高的運行或者存儲效率。數據結構往往同高效的檢索算法索引技術有關。

2.數據結構是指相互之間存在着一種或多種關係的數據元素的集合和該集合中數據元素之間的關係組成。記爲:
Data_Structure=(D,R)
其中D是數據元素的集合R是該集合中所有元素之間的關係的有限集合

研究對象包括哪些?

一、數據的邏輯結構:指反映數據元素之間的邏輯關係的數據結構,其中的邏輯關係是指數據元素之間的前後件關係,而與他們在計算機中的存儲位置無關。邏輯結構包括:
1.集合
二、數據的物理結構:指數據的邏輯結構在計算機存儲空間的存放形式。

重要意義??


答:一般認爲,一個數據結構是由數據元素依據某種邏輯聯繫組織起來的。對數據元素間邏輯關係的描述稱爲數據的邏輯結構;數據必須在計算機內存儲,數據的存儲結構是數據結構的實現形式,是其在計算機內的表示;此外討論一個數據結構必須同時討論在該類數據上執行的運算纔有意義。一個邏輯數據結構可以有多種存儲結構,且各種存儲結構影響數據處理的效率。
在許多類型的程序的設計中,數據結構的選擇是一個基本的設計考慮因素。許多大型系統的構造經驗表明,系統實現的困難程度和系統構造的質量都嚴重的依賴於是否選擇了最優的數據結構。許多時候,確定了數據結構後,算法就容易得到了。有些時候事情也會反過來,我們根據特定算法來選擇數據結構與之適應。不論哪種情況,選擇合適的數據結構都是非常重要的。
選擇了數據結構,算法也隨之確定,是數據而不是算法是系統構造的關鍵因素。這種洞見導致了許多種軟件設計方法和程序設計語言的出現,面向對象的程序設計語言就是其中之一。


結構分類

數據結構是指同一數據元素類中各數據元素之間存在的關係。數據結構分別爲邏輯結構存儲結構物理結構)和數據的運算。數據的邏輯結構是對數據之間關係的描述,有時就把邏輯結構簡稱爲數據結構。邏輯結構形式地定義爲(K,R)(或(D,S)),其中,K是數據元素的有限集,R是K上的關係的有限集。
根據數據元素間關係的不同特性,通常有下列四類基本的結構: ⑴集合結構。該結構的數據元素間的關係是“屬於同一個集合”。 ⑵線性結構。該結構的數據元素之間存在着一對一的關係。 ⑶樹型結構。該結構的數據元素之間存在着一對多的關係。 ⑷圖形結構。該結構的數據元素之間存在着多對多的關係,也稱網狀結構。 從上面所介紹的數據結構的概念中可以知道,一個數據結構有兩個要素。一個是數據元素的集合,另一個是關係的集合。在形式上,數據結構通常可以採用一個二元組來表示。
數據結構的形式定義爲:數據結構是一個二元組 :Data_Structure=(D,R),其中,D是數據元素的有限集,R是D上關係的有限集。線性結構的特點是數據元素之間是一種線性關係,數據元素“一個接一個的排列”。在一個線性表數據元素的類型是相同的,或者說線性表是由同一類型的數據元素構成的線性結構。在實際問題中線性表的例子是很多的,如學生情況信息表是一個線性表:表中數據元素的類型爲學生類型; 一個字符串也是一個線性表:表中數據元素的類型爲字符型,等等。
線性表是最簡單、最基本、也是最常用的一種線性結構。 線性表是具有相同數據類型的n(n>=0)個數據元素的有限序列,通常記爲: (a1,a2,… ai-1,ai,ai+1,…an) ,其中n爲表長, n=0 時稱爲空表。 它有兩種存儲方法:順序存儲和鏈式存儲,它的主要基本操作是插入、刪除和檢索等。
數據結構在計算機中的表示(映像)稱爲數據的物理(存儲)結構。它包括數據元素的表示和關係的表示。數據元素之間的關係有兩種不同的表示方法:順序映象和非順序映象,並由此得到兩種不同的存儲結構:順序存儲結構和鏈式存儲結構
順序存儲方法:它是把邏輯上相鄰的結點存儲在物理位置相鄰的存儲單元裏,結點間的邏輯關係由存儲單元的鄰接關係來體現,由此得到的存儲表示稱爲順序存儲結構。順序存儲結構是一種最基本的存儲表示方法,通常藉助於程序設計語言中的數組來實現。
鏈接存儲方法:它不要求邏輯上相鄰的結點在物理位置上亦相鄰,結點間的邏輯關係是由附加的指針字段表示的。由此得到的存儲表示稱爲鏈式存儲結構,鏈式存儲結構通常藉助於程序設計語言中的指針類型來實現
索引存儲方法:除建立存儲結點信息外,還建立附加的索引表來標識結點的地址
散列存儲方法:就是根據結點的關鍵字直接計算出該結點的存儲地址。
數據結構中,邏輯上(邏輯結構:數據元素之間的邏輯關係)可以把數據結構分成線性結構和非線性結構。線性結構的順序存儲結構是一種順序存取的存儲結構,線性表的鏈式存儲結構是一種隨機存取的存儲結構。線性表若採用鏈式存儲表示時所有結點之間的存儲單元地址可連續可不連續。邏輯結構與數據元素本身的形式、內容、相對位置、所含結點個數都無關。


常用結構

數組 (Array)

在程序設計中,爲了處理方便, 把具有相同類型的若干變量按有序的形式組織起來。這些按序排列的同類數據元素的集合稱爲數組。在C語言中, 數組屬於構造數據類型。一個數組可以分解爲多個數組元素,這些數組元素可以是基本數據類型或是構造類型。因此按數組元素的類型不同,數組又可分爲數值數組、字符數組、指針數組、結構數組等各種類別。

棧 (Stack)

是只能在某一端插入和刪除的特殊線性表。它按照先進後出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最後一個數據被第一個讀出來)。

隊列 (Queue)

一種特殊的線性表,它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作。進行插入操作的端稱爲隊尾,進行刪除操作的端稱爲隊頭。隊列是按照“先進先出”或“後進後出”的原則組織數據的。隊列中沒有元素時,稱爲空隊列。

鏈表 (Linked List)

是一種物理存儲單元上非連續、非順序的存儲結構,它既可以表示線性結構,也可以用於表示非線性結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱爲結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。

樹 (Tree)

是包含n(n>0)個結點的有窮集合K,且在K中定義了一個關係N,N滿足 以下條件:
(1)有且僅有一個結點 K0,他對於關係N來說沒有前驅,稱K0爲樹的根結點。簡稱爲根(root)。  (2)除K0外,K中的每個結點,對於關係N來說有且僅有一個前驅。
(3)K中各結點,對關係N來說可以有m個後繼(m>=0)。

圖 (Graph)

圖是由結點的有窮集合V和邊的集合E組成。其中,爲了與樹形結構加以區別,在圖結構中常常將結點稱爲頂點,邊是頂點的有序偶對,若兩個頂點之間存在一條邊,就表示這兩個頂點具有相鄰關係。

堆 (Heap)

在計算機科學中,堆是一種特殊的樹形數據結構,每個結點都有一個值。通常我們所說的堆的數據結構,是指二叉堆。堆的特點是根結點的值最小(或最大),且根結點的兩個子樹也是一個堆。

散列表 (Hash)

若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上。由此,不需比較便可直接取得所查記錄。稱這個對應關係f爲散列函數(Hash function),按這個思想建立的表爲散列表

關於數據結構的簡單例子


/*
 ============================================================================
 Name        : D_LinkList.c
 Author      : 谷建鵬
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */


#include <stdio.h>
#include <stdlib.h>


typedef int DataType; //將int類型重新定義一個新的類型DataType
typedef struct LNode{ //定義結構體,實際上就是結點
DataType data; //定義數據域
    struct LNode *next; //定義指針域
}LinkList;


//再定義一個結點
typedef LinkList Node;


/*
 * 功能:創建並且初始化
 * 參數:整數,用於創建第一個結點
 * 返回值:返回頭指針
 * 思路:
 * 1)先要創建頭指針
 *    (1)頭指針的數據域 存放當前線性表的長度
 *    (2)指針域指向空
 * 2)創建第一個結點
 *    (1)數據域 存 函數傳遞過來的參數
 *    (2)指針域指向空
 *    (3)修改頭指針的指向爲新創建的指針
 * 3)返回頭指針
 */
LinkList * Create_LinkList(DataType data){ //創建頭指針


LinkList *head = (LinkList *)malloc(sizeof(LinkList));
if(head!=NULL){
        Node *p = (Node*)malloc(sizeof(Node)); //創建第一個結點
        if(p!=NULL){


p->data = data;
p->next = NULL; //設定數據域和指針域




head->next = p; //設定頭指針的指針域
head->data = 1; //設定頭指針的數據域
        }else{
        printf("第一個結點創建失敗!\n");
        }
        //返回頭結點的指針
        return head;
}else{
printf("頭結點創建失敗!\n");
return NULL;
}
}


/*
 * 功能:打印線性鏈表
 * 參數:LinkList *head  (線性鏈表的頭指針)
 * 返回值:void
 * 思路:
 * 1)定義一個指針變量,獲取第一個元素(p = head->next)
 * 2)循環遍歷,條件是:p->next!=NULL
 * 3)打印p指向的數據域  :p->data
 */
void Print_LinkList(LinkList *head){
//定義一個指針變量,讓其指向線性鏈表的第一個元素
Node *p = head->next;       //head->next肯定是第一個元素
while(p!=NULL){
printf("%d\t",p->data);


        p=p->next; //讓p向下移動
}
printf("\n");
}




/*
 * 功能:線性單鏈表的添加新的元素
 * 參數:LinkList *head,DataType data
 * 返回值:void
 * 思路:
 * 插入一個元素到我們的線性鏈表中,有兩種方法:
 * 頭插法
 *    每次在頭結點之後插入一個元素
 * 尾插法(作業)
 *    每次在最後一個元素之後插入新的元素
 *
 * 使用頭插法,實現新元素的插入的步驟:
 * 1)先給新元素申請內存空間
 * 2)設置新元素的數據域和指針域
 * 3)設置頭指針數據域和指針域
 *
 */
void Insert_LinkList(LinkList *head,DataType data){
//申請新的空間
Node *new = (Node*)malloc(sizeof(Node));
if(new!=NULL){


new->data = data; //設定新的元素的數據域和指針域
new->next = head->next;


head->next = new; //讓head執行新添加的數據
head->data++;
}else{
printf("插入數據,空間申請失敗!\n");
}
}


/* 功能:刪除結點
 * 參數:LinkList *head,DataType data
 * 返回值:int (返回刪除數據所在的位置)
 * 思路:
 * 1、根據頭指針的指向,找到第一個元素,並且定義一個新的指針指向它
 * 2、判斷要刪除的是否是第一個結點
 * 3、如果不是第一個結點
 */
int Delete_LinkList(LinkList *head,DataType data){
Node *p = head->next;  //p指向了第一個結點
//進行刪除的時候臨時存儲結點的信息
    Node *temp;
    int loc=0;
    while(p!=NULL){
        loc++;
    //判斷要刪除的是不是當前元素
    if(p->data == data){
    //把第二個元素的信息存儲到temp中
    temp = p->next;
    free(p);
    head->next = temp;
    head->data --;
    break;
    }else if(p->next->data == data){
    //判斷是不是下一個元素
    temp = p->next;
    p->next = p->next->next;
    free(temp);
    head->data --;
    loc++;
    break;
    }else{
       //指針下移
    p = p->next;
    }


    }
    return loc;
}




/* 功能:按值查找
 * 參數:LinkList *head,DataType data
 * 返回值:int 位置
 * 思路:
 * 1)定義一個指針變量,讓其指向第一個元素
 * 2)判斷指針指向的值,是否等於要查找的值
 * 3)如果等於,則返回位置,如果不等於則指針下移   p = p->next;
 */
int SearchByData_LinkList(LinkList *head,DataType data){


Node *p  = head->next;
int loc=0;
while(p!=NULL){
        loc++;
        //判斷當前指針指向的值是否是要查找的值,如果是,則停止
if(p->data == data){
break;
}else{
//如果不是,則指針下移
p = p->next;
}


}


return loc;
}




/* 功能:按值查找
 * 參數:LinkList *head,DataType oldData,DataType newData
 * 返回值:void
 * 思路:
 * 1)定義一個指針變量,讓其指向第一個元素
 * 2)判斷指針指向的值,是否等於要查找的值
 * 3)如果等於,則修改原來的值=新的值(p->data=newData),如果不等於則指針下移   p = p->next;
 */
void ModifyByData_LinkList(LinkList *head,DataType oldData,DataType newData){


Node *p  = head->next;


while(p!=NULL){
        //判斷當前指針指向的值是否是要查找的值,如果是,則停止
if(p->data == oldData){
//修改當前指針的值爲要修改的值
p->data = newData;
break;
}else{
//如果不是,則指針下移
p = p->next;
}
}
}




int main(void) {


//定義線性鏈表,並且初始化
LinkList *llist = Create_LinkList(7);
//打印線性表的內容
    Print_LinkList(llist);
    //插入數據
    Insert_LinkList(llist,58);
    Print_LinkList(llist);




    Insert_LinkList(llist,90);
    Insert_LinkList(llist,88);
    Insert_LinkList(llist,60);
    Print_LinkList(llist);


    Delete_LinkList(llist,60);
    Print_LinkList(llist);


    printf("刪除的位置是:%d\n",Delete_LinkList(llist,7));
    Print_LinkList(llist);
    printf("線性鏈表的長度:%d\n",llist->data);
    printf("58的位置是:%d\n",SearchByData_LinkList(llist,58));


    ModifyByData_LinkList(llist,58,588);
    Print_LinkList(llist);


return EXIT_SUCCESS;
}






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