1. 程式人生 > >浙江中醫藥大學-《資料結構》(C語言版)-第一章-第二章概念與程式碼

浙江中醫藥大學-《資料結構》(C語言版)-第一章-第二章概念與程式碼

ZCMU-Data StructureC language

Part 1 Exordium

1Data:能夠輸入到計算機中並被計算機程式處理的符號的總稱。

2Data Element:資料的基本單位,資料元素用以完整的描述一個物件。

3Data Item:組成資料元素、有獨立含義、不可分割的最小單位

4Data Object:性質相同的資料元素的集合。

5、資料結構的三要素:資料邏輯結構、資料儲存結構、資料運算:

其中:資料的邏輯結構包含

 

資料的儲存結構(物理結構)包含:順序儲存結構、鏈式儲存結構。

6、演算法的五個特性:

    1)有窮性

    2)確定性

    3

)可行性

    4)輸入

    5)輸出

7、演算法評價標準:

    1)正確性

    2)可讀性

    3)健壯性

    4)高效性

8、演算法複雜性分析:定義1.1 在計算演算法時間複雜度時,可以忽略所有低次冪項和最高次冪項的係數,簡化演算法分析,體現增長率的含義。(例項見《資料結構 C語言版》嚴蔚敏 P13-P14 P17習題6

Part 2 Linear List

9、對於非空的線性表或線性結構,包含以下特點:

    1)存在唯一的一個被稱作第一個的資料元素。

    2)存在唯一的一個被稱作最後一個的資料元素。

    3)除第一個之外,結構中的每個資料元素均只有一個前驅。

    4)除最後一個之外,結構中的每個資料元素只有一個後繼。

10、線性表應用例項:稀疏多項式運算、圖書管理系統。

11、線性表的順序表示(順序儲存結構)指的是用一組地址連續的儲存單元依次儲存線性表的資料元素,特點是:邏輯上相鄰的資料元素、物理次序也相鄰;因此只要確定了儲存線性表的起始位置,線性表中任一資料元素都可以隨機儲存,所以線性表的順序儲存結構是一種隨機儲存的儲存結構。

12、順序表中基本操作的實現:

      1)初始化

為順序表動態分配一個預定大小的陣列空間,使elem指向這段空間的基地址。

Status InitList(Sqlist &L)
{
   L.elem=new ElemType[MAXSIZE];
   if(!L.elem) exit(OVERFLOW);
   L.length=0;
   return OK;
}

      2)取值

由於順序儲存結構具有隨機儲存的特點,可以直接通過陣列下標定位得到。elem[i-1]儲存第i個數據元素。

if(i<1||i>L.length)return ERROR; //判斷i是否合理
  e=L.elem[i-1];
  return OK;

      3)查詢

從第一個元素起,依次和e比較,若找到與e相等的元素L.elem[i],則查詢成功,返回該元素的序號i+1

for(i=0;i<L.length;i++)
    if(L.elem[i]==e) return i+1;
 return 0;

順序表查詢平均時間複雜度為On)。

      4)插入

一般情況下,在第i個位置插入一個元素時,需要從最後一個元素即第n個元素開始,依次向後移動一個位置,直至第i個元素(共n-i+1個元素)。

if((i<1)||(i>L.length+1) return ERROR; //i值不合法
  if(L.length==MAXSIZE) return ERROR; //當前儲存空間已滿
  for(j=L.length-1;j>=i-1;j--)
     L.elem[j+1]=L.elem[j];//插入位置之後元素後移
  L.elem[i-1]=e;//將新元素e放入第i個位置
  ++L.length;//表長+1

順序表插入演算法的平均時間複雜度為O(n)

     5)刪除

一般情況下,刪除第i個元素需要將第i+1個元素至第n個元素(共n-i)個元素依次向前移動一個位置(i=n時無需移動)。

if((i<1)||(i>L.length)) return ERROR ;
  for(j=i;j<=L.lenrth-1;j++)
    L.elem[j-1]=L.elem[j];//前移
    --L.length;
    return OK;

順序表刪除演算法平均時間複雜度為O(n)

13、線性錶鏈式儲存的特點:用一組任意的儲存單元儲存線性表內的資料元素,這組儲存單元可以是連續的,也可以是不連續的,因此需要包含兩個部分,一是資料本身,二是結點,結點包含兩個域,儲存資料元素資訊的為資料域,儲存直接後繼位置的域成為指標域,連結串列中的每個結點只包含一個指標域。同時由於最後一個數據元素沒有直接後繼,單鏈表中最後一個結點的指標為空。

14、連結串列增加頭結點的作用:

      1)便於首元結點的處理

      2)便於空表和非空表的統一處理

15、單鏈表是非隨機存取的儲存結構,要取得第i個數據元素必須從頭指標出發順鏈進行尋找,稱為順序存取的儲存結構。

16、單鏈表的基本操作的實現

      1)初始化

 L=new LNode;//生成新結點作為頭結點
     L->next=NULL;
     return OK;

      2)取值

//在帶頭結點的單鏈表L中根據序號i獲取元素的值,用e返回第i個數據元素的值
  p=L->next;j=1;//p指向首元結點,計數器j為1
  while(p&&j<i)//順鏈域向後掃描,直到p為空域或p指向第i個元素
  {
     p=p->next;//指向下一個結點
    ++j;
   }
    if(!p||j>i) return ERROR;
     e=p->data; //取第i個結點的資料域
     return OK;


單鏈表取值平均時間複雜度為O(n)

      3)查詢

p=L->next; //初始化,p指向首元結點
   while(p&&p->data!=e)
   p=p->next;
   return p;

單鏈表查詢平均時間複雜度為O(n)

      4)插入


p=L;j=0;
   while(p&&(j<i-1))
    {p=p->next;++j; }//查詢第i-1個結點,p指向該結點
   if(!p||j>i-1) return ERROR;
   //重點
   s=new LNode;
   s->data=e;
   s->next=p->next;
   p->next=s;
   return OK;

      5)刪除


 p=L;j=0;
  while((p->next)&&(j<i-1))
    {p=p->next;++j;}
  if(!(p->next)||(j>i-1)) return ERROR;
  //重點
  q=p->next;
  p->next=q->next;//改變刪除結點前驅結點的指標域
  delete q;
  return OK:

插入和刪除演算法平均時間複雜度均為O(n)

17、實現前插法和後插法建立單鏈表完整程式碼

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

typedef int Elem;

typedef struct Node
{
    Elem data;
    struct Node *next;
}Node,*LinkList;

LinkList LinkListBegin()
{
    Node *L;
    L=(Node *)malloc(sizeof(Node));
    if(L=NULL)
        printf("Fall");
    L->next=NULL;
}

///扦插
LinkList LinkListqiancha()
{
    Node *L;
    L=(Node *)malloc(sizeof(Node));
    L->next=NULL;

    Elem x;
    while(scanf("%d",&x)!=EOF)
    {
        Node *p;
        p=(Node *)malloc(sizeof(Node));
        p->data=x;
        p->next=L->next;
        L->next=p;
    }
    return L;
}

//後插
LinkList LinkListhoucha()
{
    Node *L;
    L=(Node *)malloc(sizeof(Node));
    L->next=NULL;
    Node *r;
    r=L;

    Elem x;
    while(scanf("%d",&x)!=EOF)
    {
        Node *p;
        p=(Node *)malloc(sizeof(Node));
        p->data=x;
        r->next=p;
        r=p;
    }
    r->next=NULL;
    return L;
}

//charu
LinkList LinkListInsert(LinkList L,int i,Elem x)
{
    Node *pre;
    pre=L;
    int temp=0;
    for(temp=1;temp<i;temp++)

        pre=pre->next;
        Node *p;
        p=(Node *)malloc(sizeof(Node));
        p->data=x;
        p->next=pre->next;
        pre->next=p;

    return L;

}

//
LinkList LinkListDelete(LinkList L, Elem x)
{
    Node *p,*pre;
    p=L->next;
    while(p->data!=x)
    {
        pre=p;
        p=p->next;
    }
    pre->next=p->next;
    delete(p);
    return L;
}

int main()
{
    LinkList list,start;
    list=LinkListqiancha();
    for(start=list->next;start!=NULL;start=start->next)
        printf("%d",start->data);
    int i;
    scanf("%d",&i);
    Elem x;
    scanf("%d",&x);
    LinkListInsert(list,i,x);
    for(start=list->next;start!=NULL;start=start->next)
        printf("%d",start->data);
    scanf("%d",&x);
    LinkListDelete(list,x);
    for(start=list->next;start!=NULL;start=start->next)
        printf("%d",start->data);
}


18、迴圈連結串列、連結串列合併

迴圈連結串列的特點是表中最後一個結點的指標域指向頭結點,整個連結串列形成一個環。

迴圈連結串列和單鏈表判斷指標p是否指向表尾的終止條件不同:

單鏈表:p!=NULLp->next!=NULL

迴圈連結串列:p!=Lp->next!=L

連結串列合併僅需將第一個表的尾指標指向第二表的第一個結點,第二個表的尾指標指向第一個表的頭結點,然後釋放第二個表的頭結點,實現程式碼:

   p=B->next->next;
   B->next=A->next;
   A->next=p;

19、儲存密度=資料元素本身佔用的儲存量/結點結構佔用的儲存量

順序表的儲存密度為1,連結串列儲存密度小於1,若不考慮順序表中的空閒區,順序表儲存空間利用率100%,單鏈表儲存空間利用率50%

20、主要操作是和元素位置緊密相關的這類取值操作,採用順序表;對於頻繁進行插入或刪除的線性表,採用連結串列。