日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构——绪论以及线性表的顺序表示

發布時間:2024/2/28 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构——绪论以及线性表的顺序表示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

緒論

數據類型

數據類型是一個值的集合和定義在此集合上一組操作的總稱。

(1)原子類型:其值不可再分的數據類型,如int,char,float。

(2)結構類型:其值可以再分解為若干成分的數據類型。

struct Student {long no;char name[10];float score; };

(3)抽象數據類型(ADT):是指一個數學模型以及定義在該模型上的一組操作。

class Student { private:long no;char name[10];float score; public:Student();void findnumber(long no);void findname(char name[]);void Print(); };

?

數據結構及其三要素

在任何問題中,數據元素都不是孤立存在的,而是在它們之間存在著某種關系,這種數據元素之間的關系稱為結構。數據結構是相互之間存在一種或多種特定關系的數據元素的集合。數據結構的三要素:邏輯結構、存儲結構(物理結構)和數據的運算

邏輯結構是指數據元素之間的邏輯關系,即從邏輯關系上描述數據。它與數據的存儲無關,是獨立于計算機的。數據的邏輯結構分為線性結構和非線性結構,線性表是典型的線性結構;集合、樹和圖是典型的非線性結構。

存儲結構是指數據結構在計算機中的表示,也稱物理結構。它包括數據元素的表示和關系。數據的存儲結構是邏輯結構用計算機語言的實現。

數據運算是對數據的處理。包括:

(1)算術運算:加減乘除等運算

(2)邏輯運算:或、且、非等運算

(3)關系運算:大于、小于、等于、不等于等運算

(4)數據傳輸:輸入、輸出、賦值等運算

?

算法的定義

算法(Algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰方法算法用系統的方法描述解決問題的策略

?

五個特性

(1)有窮性(Finiteness):算法的有窮性是指算法必須能在執行有限個步驟之后終止;

(2)確切性(Definiteness):算法的每一步驟必須有確切的定義;

(3)輸入項(Input):一個算法有0個或多個輸入,以刻畫運算對象的初始情況,所謂0個輸入是指算法本身定出了初始條件;

(4)輸出項(Output):一個算法有一個或多個輸出,以反映對輸入數據加工后的結果。沒有輸出的算法是毫無意義的;

(5)可行性(Effectiveness):算法中執行的任何計算步驟都是可以被分解為基本的可執行的操作步,即每個計算步都可以在有限時間內完成(也稱之為有效性)。

?

時間復雜度和空間復雜度

同一問題可用不同算法解決,而一個算法的質量優劣將影響到算法乃至程序的效率。算法分析的目的在于選擇合適算法和改進算法。一個算法的評價主要從時間復雜度空間復雜度來考慮。

時間復雜度

算法的時間復雜度是指執行算法所需要的計算工作量。一般來說,計算機算法是問題規模n 的函數f(n),算法的時間復雜度也因此記做:T(n)=Ο(f(n))。因此,問題的規模n 越大,算法執行的時間的增長率與f(n) 的增長率正相關,稱作漸進時間復雜度(Asymptotic Time Complexity)。

空間復雜度

算法的空間復雜度是指算法需要消耗的內存空間。其計算和表示方法與時間復雜度類似,一般都用復雜度的漸近性來表示。同時間復雜度相比,空間復雜度的分析要簡單得多。

?

簡介

了解緒論中的相關概念后,接下來將學習數據結構中的線性表。數據結構中的線性表分為順序表鏈表,本篇博文先總結順序表的操作和實現,在另一篇博文中再介紹鏈表的操作和實現。由于在數據結構中,棧和隊列可以用順序表實現,也能用鏈表實現。所以本篇先介紹順序表,再介紹棧和隊列的概念,最后給出相應的完整代碼。由于代碼比較多,所以鏈式結構的代碼在下一篇博文中附上。

?

線性表的定義

線性表是具有相同數據類型的n(n >= 0)個數據元素的有限序列。其中n為表長,當n = 0時,該線性表是一個空表。若用L命名線性表,其一般表示為:L = (a1, a2, ..., ai, ai+1, ..., an)。其中a1是唯一的”第一個”數據元素,an是唯一的最后一個數據元素。除第一個元素外,每個元素有且僅有一個直接前驅。除最后一個元素外,每個元素有且僅有一個直接后繼。

線性表的特點如下:

(1)表中元素的個數有限。

(2)表中元素具有邏輯上的順序性,在序列中各元素排序有其先后次序,即為線性結構。

(3)表中元素都是數據元素,每一個元素都是單個元素。

(4)表中元素具有抽象性。即僅討論元素間的邏輯關系,不考慮元素的內容。

線性表是一種邏輯結構,表示元素之間一對一的相鄰關系。順序表和鏈表是指存儲結構。在接觸一種新的數據結構類型時,都應該分別從其邏輯結構、存儲結構和對數據的操作三方面著手。

?

線性表的順序存儲稱為順序表。它用的是一組地址連續的存儲單元(數組),依次存儲線性表中的數據元素,從而使得邏輯上相鄰的兩個元素在物理位置上也相鄰。順序表的邏輯順序與其物理順序相同。順序表最主要的特點是隨機訪問。即通過首地址和元素序號可以在O(1)的時間內找到指定的元素。順序表的存儲密度高,每個結點只存儲數據元素。因為其元素物理上相鄰,所以插入和刪除操作需要移動大量元素。其存儲類型可描述為:

#define MaxSize 50 typedef struct{int data[MaxSize]; //順序表元素int length; //順序表當前長度 }SqList;

?

棧的定義

棧:是只允許在一端進行插入或刪除操作的線性表。首先棧是一種線性表,但是限定這種線性表只能在一端進行插入和刪除操作。它的一個明顯的操作特性可以概括為后進先出

棧的順序存儲稱為順序棧,它是利用一組地址連續的存儲單元存放自棧底到棧頂的數據元素,同時設置了一個指針(top)指向它的當前位置。棧的順序存儲類型可描述為:

#define Maxsize 50 typedef struct{Elemtype data[Maxsize]; ????//存放棧中元素int top; ????????????????? ?//棧頂指針 }Sqstack;

棧頂指針:S.top,初始化時設置S.top = -1;棧頂元素:S.data[S.top]。

進棧操作:先判斷棧是否為滿,若不滿,棧頂指針先加1,再送值到棧頂元素。

出棧操作:先判斷棧是否為空,若不空,先取棧頂元素值,再將棧頂指針減1.

棧空條件:S.top == -1; ?棧滿條件:S.top == Maxsize - 1; ?棧長:S.top + 1。

由于順序棧的入棧操作受數組上界的約束,當對棧的最大使用空間估計不足時,有可能發生棧上溢,所以要對棧是否為滿進行判斷。其實棧頂指針也可以設置為S.top = 0,只不過此時的操作也要發生相應的變化。當棧頂指針設置為-1,存放數據時要先加后放。而棧頂指針設置為0,存放數據時要先放后加

基本操作:

int Push(Seqstack *S,Stackelemtype e) //入棧 {if(Isfull(*S)){printf("Full!");}S->top++;S->elem[S->top]=e;?return 1; }int Pop(Seqstack *S,Stackelemtype *e) //出棧 {if(Isempty(*S)){printf("Empty!");return 0;}*e=S->elem[S->top];S->top--;return 1; }int Gettop(Seqstack S,Stackelemtype *e) //獲取棧頂元素 {if(Isempty(S)){printf("Empty!");return 0;}*e=S.elem[S.top];return 1; }

?

隊列的定義

隊列:簡稱為隊,也是一種操作受限的線性表,只允許在表的一端進行插入,而在另外一端進行刪除。其操作特性是先進先出

隊列的順序存儲

隊列的順序實現是指分配一塊連續的存儲單元存放隊列中的元素,并附設兩個指針front和rear分別指向隊頭元素和隊尾元素的位置。設隊頭指針指向隊頭元素,隊尾指針指向隊尾元素的下一個位置。隊列的順序存儲類型可描述為:

#define Maxsize 50 typedef struct{Elemtype data[Maxsize]; ???? ?//存放隊列元素int front,rear; ??????????????//隊頭指針和隊尾指針 }SqQueue;

這里需要了解循環隊列的概念,將順序隊列想象成一個環狀的空間,即把存儲隊列元素的表從邏輯上看成一個環。當隊首指針Q.front = Maxsize - 1后,再前進一個位置就自動到0,這可以利用除法取余運算(%)來實現。

初始狀態:Q.front = Q.rear = 0;

隊首指針加1:Q.front = (Q.front + 1)%Maxsize;

隊尾指針加1:Q.rear = (Q.rear + 1)%Maxsize;

?

為了區分隊空和隊滿,有三種處理方式:

(1)犧牲一個單元來區分隊空和隊滿,入隊時少用一個隊列單元,這是一種較為普遍的做法,約定以隊頭指針在隊尾指針的下一個位置作為隊滿的標志

隊滿條件為:(Q.rear + 1)%Maxsize == Q.front。

對空條件為:Q.front == Q.rear。

隊列中元素的個數:(Q.rear - Q.front + Maxsize)%Maxsize。

(2)類型中增添表示元素個數的數據成員。這樣,則隊空的條件為Q.size == 0;隊滿的條件為Q.size == Maxsize。這兩種情況都有Q.front == Q.rear。

(3)類型中添加tag數據成員,以區分是隊滿還是隊空。tag等于0的情況下,若因刪除導致Q.front == Q.rear則為隊空;tag等于1的情況下,若因插入導致Q.front == Q.rear則為隊滿。

基本操作:

int Enter(SeqQueue *Q,Queueelemtype e) //入隊 {if((Q->rear+1)%MAXSIZE==Q->front){printf("Queue is full!");return 0;}Q->element[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;return 1; }int Delete(SeqQueue *Q,Queueelemtype *e) //出隊 {if(Q->front==Q->rear){printf("Queue is empty!");return 0;}*e=Q->element[Q->front];Q->front=(Q->front+1)%MAXSIZE;return 1; }

?

線性表 Linearlist.c

#include <stdio.h> #define MAXSIZE 100 typedef int Elemtype;typedef struct Linearlist {Elemtype elem[MAXSIZE];int last; }Seqlist; /*這里有一點要注意,若傳的參數是Seqlist *L,即傳的是地址,就要寫成 指針形式,L->last和L->elem[], 若傳的是Seqlist L,即一個結構體類型, 就寫成L.last和L.elem[]*/void Initlist(Seqlist *L) {L->last=-1; }void Destroylist(Seqlist *L) {L->last=-1; }void Clearlist(Seqlist *L) {L->last=-1; }int Emptylist(Seqlist L) {if(L.last==-1){return 1;}else{return 0;} }int Lengthlist(Seqlist L) {if(L.last==-1){return 0;}else {return (L.last+1);} }int Locate(Seqlist L,Elemtype e) //傳的參數是Seqlist L {int i=0;while(i<=L.last&&L.elem[i]!=e){i++;}if(i>L.last){return -1;}else{return(i+1);} }int Getdata(Seqlist L,int i) {if(0<i&&i<=(L.last+1)){return L.elem[i-1];}else{return -1;} }int Insertlist(Seqlist *L,int i,Elemtype e) //傳的是指針,寫成L->last和L->elem[] {int k;if((i<1)||(i>L->last+2)){return 0;}for(k=L->last;k>=i-1;k--){L->elem[k+1]=L->elem[k];}L->elem[i-1]=e;L->last++;return 1; }int Deletelist(Seqlist *L,int i,Elemtype *e) {int k;if(i<1||i>L->last+1){return 0;}*e=L->elem[i-1];for(k=i-1;k<L->last;k++){L->elem[k]=L->elem[k+1];}L->last--;return 1; }void Traverselist(Seqlist L) {int i=0;if(!Emptylist(L)){for(;i<=(L.last);i++){printf("%4d",L.elem[i]);}printf("\n");} }void Merge(Seqlist *LC,Seqlist *LA,Seqlist *LB) {int i,j,l;i=0;j=0;l=0;while(i<=LA->last&&j<=LB->last){if(LA->elem[i]<LB->elem[j]){LC->elem[l]=LA->elem[i];l++;i++;LC->last++;}}while(i<=LA->last){LC->elem[l]=LA->elem[i];i++;l++;LC->last++;}while(j<=LB->last){LC->elem[l]=LB->elem[j];l++;j++;LC->last++;} }int main() {int i,e=0;Seqlist L,LA,LB,LC;Initlist(&L);Initlist(&LA);Initlist(&LB);Initlist(&LC);for(i=1;i<=20;i++){Insertlist(&L,i,i);Insertlist(&LA,i,i+10);Insertlist(&LB,i,i+30*2);}Traverselist(L);Traverselist(LA);Traverselist(LB);Deletelist(&L,3,&e);printf("Deleted elem is:%4d\n",e);Traverselist(L);e=Locate(L,25);printf("Get the index of elem:%4d\n",e);e=Getdata(L,13);printf("Get the figure of elem:%4d\n",e);Merge(&LC,&LA,&LB);Traverselist(LC);return 0;}

?

順序表實現棧 Stack.c

#include <stdio.h> #define Stacksize 50typedef int Stackelemtype;typedef struct Stack {Stackelemtype elem[Stacksize];int top; }Seqstack;void Initstack(Seqstack *S) {S->top=-1; }void Clearstack(Seqstack *S) {S->top=-1; }int Isempty(Seqstack S) {if(S.top==-1){return 1;}else{return 0;} }int Isfull(Seqstack S) {if(S.top==Stacksize-1){return 1;}else{return 0;} }int Push(Seqstack *S,Stackelemtype e) {if(Isfull(*S)){printf("Full!");}S->top++;S->elem[S->top]=e; return 1; }int Pop(Seqstack *S,Stackelemtype *e) {if(Isempty(*S)){printf("Empty!");return 0;}*e=S->elem[S->top];S->top--;return 1; }int Gettop(Seqstack S,Stackelemtype *e) {if(Isempty(S)){printf("Empty!");return 0;}*e=S.elem[S.top];return 1; }int main() {int i=1;int c;//定義棧Seqstack S;//初始化棧Initstack(&S);//入棧操作printf("Input:");while(1){scanf("%d",&c);if(c==999) break;Push(&S,c);}//獲得棧頂元素Gettop(S,&c);printf("The top element of stack is:[%d]\n",c);//出棧操作printf("Pop element:");while(Isempty(S)!=1){Pop(&S,&c);printf("[%d]",c);}printf("\n");return 0; }

?

順序表實現隊列 Squeue.c

#include <stdio.h> #define MAXSIZE 50typedef int Queueelemtype;typedef struct Squeue {Queueelemtype element[MAXSIZE];int front;int rear; }SeqQueue;void Init(SeqQueue *Q) {Q->front=Q->rear=0; }int Enter(SeqQueue *Q,Queueelemtype e) {if((Q->rear+1)%MAXSIZE==Q->front){printf("Queue is full!");return 0;}Q->element[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;return 1; }int Delete(SeqQueue *Q,Queueelemtype *e) {if(Q->front==Q->rear){printf("Queue is empty!");return 0;}*e=Q->element[Q->front];Q->front=(Q->front+1)%MAXSIZE;return 1; }int Isempty(SeqQueue Q) {if(Q.front==Q.rear)return 1;else return 0; }int Get(SeqQueue Q,Queueelemtype *e) {if(Q.front==Q.rear){printf("Queue is empty!");return 0;}*e=Q.element[Q.front];return 1; }int main() {int a;SeqQueue Q;Init(&Q);printf("Input:");while(1){scanf("%d",&a);if(a==999){break;}Enter(&Q,a);}Get(Q,&a);printf("Get the element of queue:");printf("[%d]\n",a);printf("Numbers of queue:");while(Isempty(Q)!=1){Delete(&Q,&a);printf("[%d]",a);}printf("\n");return 0; }

總結

以上是生活随笔為你收集整理的数据结构——绪论以及线性表的顺序表示的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。