線性表順序存儲基本操作


  • 線性表的基本操作
 //線性表的基本操作
 /*
    Status,自定義的一個枚舉類型,
    enum Status{
           success(成功),fail(失敗),fatal(內存分配失敗),range_error(連續空間訪問失敗越界) 
    } 
 */
 Status List_Init(SqListPtr L);//初始化線性表
 void List_Clear(SqListPtr L);//清空線性表
 void List_Destory(SqListPtr L);//銷毀線性表 
 bool List_Empty(SqListPtr L);//判斷線性表是否為空
 int List_Size(SqListPtr L);//線性表中元素的個數或線性表的長度
 Status List_Retrival(SqListPtr L,int pos,ElemType *elem);//在線性表L中的pos那個位置取出數據放在elem指針中
 Status List_Locate(SqListPtr L,ElemType elem,int *pos);//在線性表L中找出元素elem的位置放在pos指針中
 Status List_Prior(SqListPtr L,int pos,ElemType *elem);//在線性表L中求出pos那個位置元素的直接前驅放在elem指針中
 Status List_Next(SqListPtr L,int pos,ElemType *elem);//在線性表L中求出pos那個位置元素的直接后繼放在elem指針中 
 //以上函數的參數是指針類型的,通常是指:我們希望通過函數所獲得結果放到指針當中
 Status List_Insert(SqListPtr L,int pos,ElemType elem);//在線性表中插入一個元素
 Status List_Delete(SqListPtr L,int pos)://在線性表中刪除一個元素 
  • 定義線性表結構體(空間分配,靜態:數組;動態:指針)
 //定義線性表的結構體
 #define LIST_TNIT_SIZE 100 //線性表初始大小100
 #define LIST_INCREAMENT 10 //增量
 typedef int ElemType;
 typedef struct SqList{
     ElemType *elem;//elem指針,指向ElemType數據元素類型,連續存儲空間的首地址的指針 
     int length=0;//線性表的長度,初始線性表的長度為0 
     int list_size;//線性表內存空間的大小 
 }SqList,*ptr;
 typedef ptr SqListPtr; 

 一、線性表的順序存儲結構

1、初始化—創建線性表

 //初始化,創建線性表
 Status List_Init(SqListPtr L){
     Status s=success;//狀態初始假設是成功的
     L->list_size=LIST_INIT_SIZE;
     L->length=0;//沒有數據元素,線性表的初始長度為0
     L->elem=(ElemType*)malloc(sizeof(ElemType)*L->list_size);
    if(L->elem==NULL)
         s=fatal;//內存分配失敗,創建線性表失敗 
     return s; //返回函數狀態 
 } 

2、線性表順序存儲結構上的查找(按位置查找值、按值查找位置)

  •  按位置查找值,首先確保位置是合法的,若查找成功,返回位置元素的詳細信息,否則返回錯誤信息
 //按位置查找 
 Status List_Retrival(SqListPtr L,int pos,ElemType *elem){//查找在線性表pos位置的元素,放在elem指針中,該函數實現查找是否成功的狀態信息 
     Status s=range_error;//假設初始狀態,找不到,發生越界錯誤
    if(L){//如果線性表存在 
        if((pos-1)>=0&&(pos-1)<L->length){//判斷位置的合法性,邏輯位置與實際位置差1 
             *elem=L->elem[pos-1];//將查找pos位置的元素放在elem指針中
             s=success//函數狀態返回查找成功 
         }
     else
         s=fatal;//查找失敗
     return s;//返回函數狀態     
 } 
  • 按值查找位置,需要將線性表中的每一個元素進行比較,從第一個元素開始,一直比較到最后一個元素,時間復雜度根據差找的元素位置不同而有所,若查找的元素在線性表的前面,則查找速度快些,若在后面,則查找的速度慢些。
//按值查找
Status List_Locate(SqListPtr L,ElemType elem,int *pos){//找elem在線性表L當中的位置放在pos指針中 
    Status s=range_error;
    if(L){//如果線性表存在
        for(int i=0;i<L->length;i++){//對線性表中每一個元素和elem比較是否相等,如果相等則查找成功,否則查找失敗 
            if(L->elem[i]==elem){
                *pos=i+1;
                s=success;
                break;
            }
        } 
    }
    else
        s=fatal;//查找失敗
    return s;//返回函數的狀態 
} 

注:如果找到了就不找到需要再往后面找了,break跳出for循環,該按值查找的時間復雜度,最好的情況就是在第一個位置就找到,只需要比較1次,最壞的情況所查元素在最后一個或沒有,需要比較n次,平均比較n/2次,時間復雜度是O(n)。

 3、線性表的順序存儲—插入操作

  • 檢查插入位置是否合法,如果合法則繼續,否則退出。
  • 判斷表是否占滿,因為事先分配空間,可能存在所分配的存儲空間全部被占用的情況,此時也不能事先插入。
  • 若前面檢查通過,則數據元素依次向后移動一個位置,為避免覆蓋源數據,應從最后一個依次向前移動。
  • 新的數據元素放到恰當的位置。
  • 表長加1。
    //線性表的順序存儲—插入操作
    Status List_Insert(SqListPtr L,int pos,ElemType elem){//在線性表中pos位置插入新元素elem 
        Status s=range_error;
        if((pos-1)>=0&&(pos-1)<L->length-1){//如果插入位置合法 
            if(L&&L->length<L->List_Size){//如果線性表存在 
                for(int i=L->length-1;i>=pos-1;i--)
                    L->elem[i+1]=L->elem[i];//從最后一個元素開始向后移動 
                 L->elem[pos-1]=elem;//將元素插入指定的pos位置
                 L->length++;//最后表長加1
                 s=success;
            }
        }
        else
            s=fail;//插入失敗
        return s; //返回函數狀態
    } 

注:順序表上實現插入操作需要移動表中一辦的數據元素。時間復雜度為O(n),最壞的情況是在第一個元素插入(i=1),需要向后移動n個元素。這種順序存儲結構需要移動大量的數據元素,而每個數據元素可能是占據很大的內存空間,所以這種方法的效率是很低的。

4、線性表的順序存儲—刪除操作

  • 檢查刪除位置是否合法,同時判斷線性表是否為空,因為空的線性表不能進行刪除操作
  • 若檢查通過,數據元素依次向前移動一個位置
  • 表長減1
//線性表的順序存儲—刪除操作
Status List_Delete(SqListPtr L,int pos){//在線性表L中的pos位置刪除元素 
    Status s=range_error;
    if((pos-1)>=0&&(pos-1)<L->length){//判斷刪除位置是否合法 
        if(L&&L->length>0){//判斷線性表是否存在,且不為空 
            for(int i=pos-1;i<L->length;i++)
                L->elem[i]=L->elem[i+1];//移動 
            L->length--;//表長減1 
            s=success;//修改狀態 
        }
    }
    else
         s=fail;//刪除失敗
    return s; //返回函數狀態
} 

注:插入和刪除的基本操作就是移動數據元素,最好的情況下,刪除最后一個,移動一個元素;最差的情況下,刪除第一個元素,移動n-1個元素;平均情況下:刪除第i個元素,需要移動第n-i個元素

5、銷毀線性表

//銷毀線性表
void List_Destry(SqListPtr L){
    if(L->elem)
        free(L->elem);//釋放指針 
    L->length=0;//表長置0 
} 

6、清空線性表

void List_Clear(SqListPtr L){
    L->length=0;
} 

7、判斷線性表是否為空

//判斷線性表是否為空
bool List_Empty(SqListPtr L){
    if(L->length==0)
        return true;
    else
        return false;
} 
//或者用下面的函數也可以判斷
bool List_Empty(SqListPtr L){
    return L->length==0;
} 

8、求線性表的前驅

Status List_Prior(SqListPtr L,int pos,ElemType *elem){//求線線表pos位置元素的前驅,將結果存放在elem指針中 
    Ststus s=fail;
    if(pos>=2&&pos<=L->length){//判斷pos位置是否合法 
        *elem=L->elem[pos-2];
        s=success;
    }
    else
        s=fail;
    return s;
}

9、求線性表長度

//求線性表長度
int List_Length(SqListPtr L){
    return L->length;
}

10、求線性表的后繼

//求線性表的后繼
Status List_Next(SqListPtr L,int pos,ElemType *elem){//求線性表pos位置元素的后繼,將結果存放在elem指針中 
    Status s=fail;
    if(pos>=1&&pos<L->length){//判斷pos位置是否合法 
        *elem=L->elem[pos];
        s=successs; 
    }
    else
        s=fail;
    return s;
} 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM