1. 程式人生 > >考研王道數據結構-順序表(綜合應用1)

考研王道數據結構-順序表(綜合應用1)

typedef SQ src 動態分配 作用 測試 value com 順序表

本節代碼主要來自王道單科18頁的綜合應用題。

一、18頁第1題。從順序表中刪除具有最小值的元素(假設唯一)並由函數返回被刪元素的值。
空出的位置由最後一個元素填補,若順序表為空則顯示出錯信息並退出運行


核心代碼:
 bool DeleteMinElem(Sqlist &L,ElemType &value){
// 18頁第1題。從順序表中刪除具有最小值的元素(假設唯一)並由函數返回被刪元素的值。
//空出的位置由最後一個元素填補,若順序表為空則顯示出錯信息並退出運行
    if(L.length==0){
        printf("順序表為空");
        return
0; } int pos=0; value=L.data[0]; for(int i=1;i<L.length;i++){ if(L.data[i]<value){ value=L.data[i]; pos=i; } } L.data[pos]=L.data[L.length-1]; L.length--; return 1; }

 

二、18頁第2題。設計一個高效的算法,將順序表的所有元素逆置,要求算法的空間復雜度為O(1)

核心代碼:

可以有兩種方式:

第一種:定義兩個循環指針i,j,其中i向後遍歷,j向前遍歷,這種更好記憶。

void Reverse(Sqlist &L){
    int i,j;
    ElemType temp;
    for(i=0,j=L.length-1;i<j;i++,j--){
        temp=L.data[i];
        L.data[i]=L.data[j];
        L.data[j]=temp;
    }
}

第二種:j沒有定義出來,用i和L.length(即L.length-i-1)的關系來表示其對稱位置。

void Reverse2(Sqlist &L){
    
int i; ElemType temp; for(i=0;i<L.length/2;i++){ temp=L.data[i]; L.data[i]=L.data[L.length-i-1]; L.data[L.length-i-1]=temp; } }

三、18頁第3題。刪除線性表中所有值為x的元素。要求時間復雜度O(n),空間復雜度O(1)。

核心代碼:

可以有三種方式:

第一種:遍歷時統計等於x的個數count,將不等於x的元素向前移動count個位置。

void DeleteElemX1(Sqlist &L,ElemType x){
    int count=0;//計算元素等於x的個數
    for(int i=0;i<L.length;i++){
        if(L.data[i]==x)
            count++;
        else
            L.data[i-count]=L.data[i];
    } 
    L.length-=count;       
}

第二種:把不等於x的元素重新覆蓋,個數為count。
此處count起到了統計不等於x的個數(即剩余元素的個數),也起到了覆蓋元素時的遍歷作用。

void DeleteElemX2(Sqlist &L,ElemType x){
    int count=0;//這次是計算不等於x的個數
    for(int i=0;i<L.length;i++){
        if(L.data[i]!=x){
            L.data[count]=L.data[i];
            count++; //註意這一句要在後面,因為覆蓋元素位置從0開始。 
        }
    } 
    L.length=count;  //這句不要忘了。 
} 

第三種:用頭尾兩個指針i,j從兩端向中間移動,凡遇到左端值x的元素時,直接將最右端值非x的元素左移至值為x的數據元素位置,直到兩指針相遇。

但這種方法會改變原表元素的相對位置。不推薦。就暫時不寫了。

以下是以上三道題的全部測試代碼(可直接運行):

#include<stdio.h>
#define true 1
#define false 0
#define MaxSize 100          //定義線性表的最大長度 
#define ElemType int
#define Status int 


typedef struct{
    ElemType data[MaxSize];        //動態分配數組的指針
    int length;            //當前個數 
}Sqlist;

//構造一個空的線性表L 
void InitList(Sqlist &L){
    L.length=0;
}

bool ListInsert(Sqlist &L,int i,ElemType e){ 
//將元素e插到順序表L中第i個位置 
    if(i<1||i>L.length+1)
        return false;
    if(L.length>=MaxSize)
        return false;
    for(int j=L.length;j>=i;j--)
        L.data[j]=L.data[j-1];
    L.data[i-1]=e;
    L.length++;
    return true;
}

void ListLoad(Sqlist L){
    if(L.length==0){
        printf("當前順序表為空\n");
        return;
    }
    printf("當前順序表元素為:");
    for(int i=0;i<L.length;i++)
        printf("%d ",L.data[i]);
    printf("\n");
    return;
}


// 18頁第1題。從順序表中刪除具有最小值的元素(假設唯一)並由函數返回被刪元素的值。
//空出的位置由最後一個元素填補,若順序表為空則顯示出錯信息並退出運行 
bool DeleteMinElem(Sqlist &L,ElemType &value){
    if(L.length==0){
        printf("順序表為空");
        return 0; 
    }
    int pos=0;
    value=L.data[0];
    for(int i=1;i<L.length;i++){
        if(L.data[i]<value){
            value=L.data[i];
            pos=i;
        }
    }
    L.data[pos]=L.data[L.length-1];
    L.length--;
    return 1;
}



void Reverse1(Sqlist &L){
//18頁第2題。設計一個高效的算法,將順序表的所有元素逆置,要求算法的空間復雜度為O(1)
    int i,j;
    ElemType temp;
    for(i=0,j=L.length-1;i<j;i++,j--){
        temp=L.data[i];
        L.data[i]=L.data[j];
        L.data[j]=temp;
    }
}

void Reverse2(Sqlist &L){
//18頁第2題。設計一個高效的算法,將順序表的所有元素逆置,要求算法的空間復雜度為O(1)
    int i;
    ElemType temp;
    for(i=0;i<L.length/2;i++){
        temp=L.data[i];
        L.data[i]=L.data[L.length-i-1];
        L.data[L.length-i-1]=temp;
    }
}

//遍歷時統計等於x的個數count,將不等於x的元素向前移動count個位置。 
void DeleteElemX1(Sqlist &L,ElemType x){
    int count=0;//計算元素等於x的個數
    for(int i=0;i<L.length;i++){
        if(L.data[i]==x)
            count++;
        else
            L.data[i-count]=L.data[i];
    } 
    L.length-=count;       
}

//把不等於x的元素重新覆蓋,個數為count。
//此處count起到了統計不等於x的個數(即剩余元素的個數),也起到了覆蓋元素時的遍歷作用。 
void DeleteElemX2(Sqlist &L,ElemType x){
    int count=0;//這次是計算不等於x的個數
    for(int i=0;i<L.length;i++){
        if(L.data[i]!=x){
            L.data[count]=L.data[i];
            count++; //註意這一句要在後面,因為覆蓋元素位置從0開始。 
        }
    } 
    L.length=count;  //這句不要忘了。 
} 



int main(){
    Sqlist T;
    ElemType min;
    ElemType e;
    int a;
    InitList(T);
    ListInsert(T,1,4);
    ListInsert(T,1,3);
    ListInsert(T,1,6);
    ListInsert(T,2,1);
    ListInsert(T,2,8);
    ListInsert(T,2,8);
    ListInsert(T,2,9);
    ListLoad(T);
    while(1){
        printf("1:刪除最小元素\n");  //DeleteMinElem
        printf("2:所有元素逆置(方法1)\n");   //Reverse1
        printf("3:所有元素逆置(方法2)\n");  //Reverse2 
        printf("4:刪除值等於x的所有元素(方法1)\n");   //DeleteElemX1
        printf("5:刪除值等於x的所有元素(方法2)\n");   //DeleteElemX2 
        printf("請選擇:");
        scanf("%d",&a); 
        switch(a){
            case 1:if(DeleteMinElem(T,min)) printf("成功刪除最小元素%d\n",min);    
                    else printf("刪除失敗\n");
                    break; 
            case 2:Reverse1(T);
                    break;
            case 3:Reverse2(T);
                    break;
            case 4:scanf("%d",&e);
                    DeleteElemX1(T,e);
                    break;
            case 5:scanf("%d",&e);
                    DeleteElemX2(T,e);
                    break;        
            default:return 1;
        }
        ListLoad(T);    
    }
}

刪除最小元素:

技術分享圖片

順序表逆置:

技術分享圖片

刪除值等於x的所有元素:

技術分享圖片

考研王道數據結構-順序表(綜合應用1)