資料結構,資料結構與演算法

來源:互聯網
上載者:User

資料結構,資料結構與演算法
鏈式儲存

鏈式儲存 :用一組任意的儲存單中繼存放區線性表中的資料元素。用這種方法儲存的線性表簡稱線性鏈表。

儲存鏈表中結點的一組任意的儲存單元可以是連續的,也可以是不連續的,甚至是零散分布在記憶體中的任意位置上的。鏈表中結點的邏輯順序和物理順序不一定相同。(即不要求邏輯上相鄰的元素在物理位置上也相鄰)

為了正確表示結點間的邏輯關係,在儲存每個結點值的同時,還必須儲存指示其直接後繼結點的地址(或位置),稱為指標(pointer)或鏈(link),這兩部分組成了資料元素ai的儲存映像
鏈表是通過每個結點的指標域將線性表的n個結點按其邏輯次序連結在一起的。
每一個結點只包含一個指標域的鏈表,稱為單鏈表。

為操作方便,總是在鏈表的第一個結點之前附設一個頭結點(頭指標)head指向第一個結點(即頭結點的指標域存放第一個結點的儲存位置)。頭結點的資料域可以不儲存任何資訊(或鏈表長度等資訊)。

因為最後一個資料元素沒有直接後繼,所以線性鏈表中最後一個結點的指標為空白(NULL)。

為操作方便,總是在鏈表的第一個結點之前附設一個頭結點(頭指標)head指向第一個結點(即頭結點的指標域存放第一個結點的儲存位置)。頭結點的資料域可以不儲存任何資訊(或鏈表長度等資訊)。

因為最後一個資料元素沒有直接後繼,所以線性鏈表中最後一個結點的指標為空白(NULL)。

結點的描述與實現
  C語言中用帶指標的結構體類型來描述
typedef  struct  Lnode{   ElemType  data;     /*資料域,儲存結點的值 */struct   Lnode  *next;      /*指標域,類型是struct   Lnode */}LNode, *LinkList;        /*結點的類型名 */LNode,結點結構;LinkList:鏈表結構 //LinkList L;L為單鏈表名,同時也可作為表的頭指標名,指向表中第一個結點,即L的指標域儲存第一個結點的地址。 //若L為空白,則表示線性表為空白表,其長度為0.

結點的實現
結點是通過動態分配和釋放來的實現,即需要時分配,不需要時釋放。實現時是分別使用C語言提供的標準函數:malloc() ,realloc(),sizeof() ,free() 。

動態分配 p=(LNode*)malloc(sizeof(LNode));
函數malloc分配了一個類型為LNode的結點變數的空間,並將其首地址放入指標變數p中。

動態釋放 free(p) ;
系統回收由指標變數p所指向的記憶體區。p必須是最近一次調用malloc函數時的傳回值。

演算法描述LNode  *create_LinkList(void)    /*  頭插入法建立單鏈表,鏈表的頭結點head作為傳回值  */  {    int data ;LNode *head, *p;head= (LNode  *) malloc( sizeof(LNode));head->next=NULL;     /*  建立鏈表的表頭結點head  */ while (1) //一直執行{   scanf(“%d”, &data) ;if (data==32767)  break ;p= (LNode  *)malloc(sizeof(LNode));p->data=data;     /*  資料域賦值  */p->next=head->next ;  head->next=p ;        /*  鉤鏈,新建立的結點總是作為第一個結點  */}return (head);}    // 傳回值是表頭結點head,實際就是所建立的鏈表。此時主函數中只要建一個LNode *類型的變數,即可調用該函數。如 LNode   *head;  或者LinkList  head; head=create_LinkList();
尾插入法建表

頭插入法建立鏈表雖然演算法簡單,但產生的鏈表中結點的次序和輸入的順序相反。若希望二者次序一致,可採用尾插法建表。

該方法是將新結點插入到當前鏈表的表尾,使其成為當前鏈表的尾結點。

演算法描述LNode  *create_LinkList(void)     /*  尾插入法建立單鏈表,鏈表的頭結點head作為傳回值  */  {   int data ;LNode *head, *p, *q;head=p=(LNode  *)malloc(sizeof(LNode)); p->next=NULL;        /*  建立單鏈表的表頭結點head  */while (1){    scanf(“%d”,& data);if (data==32767)  break ;q= (LNode  *)malloc(sizeof(LNode)); q->data=data;     /*   資料域賦值  */q->next=p->next;  p->next=q; p=q ;  /*鉤鏈,新建立的結點總是作為最後一個結點*/}return (head);   }
     無論是哪種插入方法,如果要插入建立單鏈表的結點是n個,演算法的時間複雜度均為O(n)。對於單鏈表,無論是哪種操作,只要涉及到鉤鏈(或重新鉤鏈),如果沒有明確給出直接後繼,鉤鏈(或重新鉤鏈)的次序必須是“先右後左”,否則就會丟掉鏈表中的一些結點。
單鏈表的尋找

(1) 按序號尋找 取單鏈表中的第i個元素。
對於單鏈表,不能象順序表中那樣直接按序號i訪問結點,而只能從鏈表的頭結點出發,沿鏈域next逐個結點往下搜尋,直到搜尋到第i個結點為止。因此,鏈表不是隨機存取結構。
設單鏈表的長度為n,要尋找表中第i個結點,僅當1≦i≦n時,i的值是合法的。

演算法思想如下:

 從頭結點開始順鏈掃描,用指標p指向當前掃描到的結點,用j作統計已掃描結點數的計數器,當p掃描下一個結點時,j自動加1。 P的初值指向頭結點,j的初值為1。當j=i時,指標p所指的結點就是第i個結點。
演算法描述ElemType   Get_Elem(LNode *L , int  i){    int j ;   LNode *p;p=L->next;  j=1;      /*  使p指向第一個結點  */while  (p!=NULL && j<i){   p=p–>next;  j++;  }        /*  移動指標p , j計數  */if  ( !p|| j>i)  return(ERROR) ; /*   p為NULL 表示i>n;  j>i表示i=0  */ else      return(p->data);}移動指標p的頻度:i=0時:0次; i∈[1,n]:i-1次;i>n:n次。∴時間複雜度: O(n)。

按值尋找
按值尋找是在鏈表中,尋找是否有結點值等於給定值key的結點? 若有,則返回首次找到的值為key的結點的儲存位置;否則返回NULL。尋找時從開始結點出發,沿鏈表逐個將結點的值和給定值key作比較。

演算法描述LNode *Locate_Node(LNode *L,int key)/*  在以L為頭結點的單鏈表中尋找值為key的第一個結點  */ {   LNode *p=L->next;while  ( p!=NULL&& p->data!=key)              p=p–>next;if  (p->data==key)   return p;else  {    printf(“所要尋找的結點不存在!!\n”); retutn(NULL); }}演算法的執行與形參key有關,平均時間複雜度為O(n)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.