1. 程式人生 > 其它 >線性表學習總結總結

線性表學習總結總結

本文分為三個方向總結線性表,佇列,堆疊。

一,線性表:

1,定義:

1 typedef int position;
2 typedef  struct LNode *List;
3 struct LNode {
4     ElementType *Data;
5     Position Last;
6 };  

就是定義一個結構,結構裡面分別是這個表的資料(也就是一個數組),還有陣列的最後一個元素

2,初始化

1 List makeempty(){
2     List T;
3     T= (List)malloc(sizeof(struct LNode));
4     T->Last = -1
; 5 return T; 6 }

3,查詢:

一共有看到兩種版本:

第一個Position Find(List L,ElementType X){
	Position i = 0;
	while(i<=L->Last&&L->Data[i]!=x){
		i++;
	}
	if(i>L->Last){
		return ERROR;
	}else{
		return i;
	}
}

Find (List L,ElementType X){ Position i; while(i<=L->Last){ if(x == L->Data[i]){ return i; } i++; } return ERROR; }

  第一個方法是通過遍歷停到與需要查詢的值相等的位置,然後停下來返回下標,第二種就是在遍歷的過程中直接找

4,插入:

首先要明確一個我一直忘記的事情就是沒有判斷是否表滿,需要插入的位置是否表滿,整體的思路就是從後往前遍歷,從L->last開始往前到需要插入的位置,把每一個i的值賦給前一個位置。

bool Insert(List L,Position p,ElementType X){
	if(L->Last = MaxSize -1){
		printf("full");
		return false;
	}
	if(P>L->Last||P<0){
		printf("ERROR");
		return false;
	}
	for(int i=L->Last;i>=P;i
--){ L->Data[i+1] = L->Data[i]; } L->Data[P] = X; L->Last++; return true; }

在p的位置,把p的值給賦給p+1位置,然後再把x插入p的位置

5,刪除:

其實刪除和插入是一樣的只是移動的方向不是一樣的,刪除是從被刪除的點開始把後面一個值賦給前一個的值。還有一個細節就是插入的時候非法位置是不包括最後一個的因為可以再最後一個位置插入值,但是在刪除中最後L->last+1的位置是沒有值的

bool Delete(List L,Position P){
    if(L->Last == -1){
        printf("empty");
        return false; 
    }
    if(L->Last<P||P<0){
        printf("illegal");
        return false;
    }
    for(Position i = P+1,i<=L->Last;i++){
        L->Data[i-1] = L->Data[i];
    }
    L->Last--;
    return true;
    
    
    
}

我覺得需要注意的就是這個迴圈的控制條件,是從p+1開始的,如果這個條件錯的話很可能會導致段錯誤。

二,佇列

1,定義:

typedef int Position;
struct QNode {
    ElementType *Data;     /* 儲存元素的陣列 */
    Position Front, Rear;  /* 佇列的頭、尾指標 */
    int MaxSize;           /* 佇列最大容量 */
};
typedef struct QNode *Queue;

2,建立空佇列:

Queue CreateQueue( int MaxSize )
{
    Queue Q = (Queue)malloc(sizeof(struct QNode));
    Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
    Q->Front = Q->Rear = 0;
    Q->MaxSize = MaxSize;
    return Q;
}

佇列需要給兩個部分分配空間,一個是整個佇列結構,一個是佇列結構中的Data陣列,那麼為什麼上面的有序陣列不需要這樣分配空間呢?有序陣列不是在結構體中也有一個數組嘛?我的理解是這個地方的佇列是有最大容量的,上面的有序陣列是一個指標只需要一個Last卡住最後的位置,而且有序表的建立是用插入的方式,需要一個數插入一個數。所以就沒必要一開始就把相應的空間給定死了。

3,判斷佇列是否為滿:

bool IsFull( Queue Q )
{
    return ((Q->Rear+1)%Q->MaxSize == Q->Front);
}

佇列如果是空的滿,那麼相應的下標應該是比Maxsize小1的,所以如果Q->rear+1%Maxsize是0,而且Q->front也是0(因為可能存在出隊的情況front不在0的位置)的話就說明佇列是滿的。只有這樣寫的話才會保證頭和尾都處於頂點。

4,判斷佇列是否為空:

bool IsEmpty( Queue Q )
{
    return (Q->Front == Q->Rear);
}

這個判斷是否為空也很經常作為佇列遍歷的迴圈條件。注意和判斷佇列是否為滿區分開來

5,插入元素:

bool AddQ( Queue Q, ElementType X )
{
    if ( IsFull(Q) ) {
        printf("佇列滿");
        return false;
    }
    else {
        Q->Rear = (Q->Rear+1)%Q->MaxSize;
        Q->Data[Q->Rear] = X;
        return true;
    }
}

首先根據前面的經驗,一旦要插入和刪除元素的時候一定要判斷所要插入的空間是不是滿了,判斷完了之後就是插入的過程,前面沒有說這個佇列的特性是順環佇列,不是我之前學的順序佇列,我之前學的佇列是tail可以一直往前走,只要保證tail始終比最後一個元素的下標大一就好了,但是這個地方的佇列的大小都是固定的所以會存在一個迴圈的問題。這個的rear的變化就是一旦rear為最後一個下標的話,就重置到第一個位置來插入元素了。

6,刪除

之前的插入時從為插入,那麼刪除的話就是從頭刪除,只要head++不就好了

ElementType DeleteQ( Queue Q )
{
    if ( IsEmpty(Q) ) { 
        printf("佇列空");
        return ERROR;
    }
    else  {
        Q->Front =(Q->Front+1)%Q->MaxSize;
        return  Q->Data[Q->Front];
    }
}

這個地方的刪除其實也是一樣,一旦一直刪除的話,刪除到最後一個數字之後,你要繼續把front放到開頭去,然後要返回所刪除掉的值。

三,堆疊

1,定義:

typedef int Position;
struct SNode {
    ElementType *Data; /* 儲存元素的陣列 */
    Position Top;      /* 棧頂指標 */
    int MaxSize;       /* 堆疊最大容量 */
};

2,判斷是否棧滿:

bool IsFull( Stack S )
{
    return (S->Top == S->MaxSize-1);
}

3,判空:

bool IsEmpty( Stack S )
{
    return (S->Top == -1);
}

記住當top是-1的時候說明棧空,這個也是堆疊初始化必須做的

4,入棧:

bool Push( Stack S, ElementType X )
{
    if ( IsFull(S) ) {
        printf("堆疊滿");
        return false;
    }
    else {
        S->Data[++(S->Top)] = X;
        return true;
    }
}

其實在目前做題中好像我很少會用 這個方式來壓入元素,其實直接寫也就是一行的程式碼。

5,出棧:

ElementType Pop( Stack S )
{
    if ( IsEmpty(S) ) {
        printf("堆疊空");
        return ERROR; /* ERROR是ElementType的特殊值,標誌錯誤 */
    }
    else 
        return ( S->Data[(S->Top)--] );
}

感覺最近一段時間有點厭學了,資料結構還是蠻難學的,競賽的書也難看的要死,pb也還沒有入門(・᷄⊖・᷅)┌∩┐,我感覺還不如沉澱一段時間來鞏固一下,學到樹就停一下把pta中樹的題目給做完把!(感覺題目都好難做 (・᷄⊖・᷅)┌∩┐ )。然後我還想把py的爬蟲學完還有一些比較有意思的庫,後面學完也丟到部落格裡面。