順序表的操作(動態)

順序表的操作(動態)

靜態定義一個順序表,是通過數組來定義, 順序表所佔的內存空間開闢在內存的棧上, 隨着函數調用的結束, 這塊內存區域會被系統自動回收;

動態定義順序表, 順序表所佔的內存空間開闢在內存的堆上, 這塊區域不會隨着函數調用的結束被系統自動回收, 而是需要程序員自己去釋放它。

順序表的基本操作

1.順序表的結構

typedef struct SeqList //SeqList可以省略
{
    ElemType elem*;//存儲空間的基址,即開闢的動態數組的首地址
    int length;//有效數字的個數,順序表當前存儲元素的個數;
    int ListSize;//用來定義開闢空間的容量

}SeqList; //這裏的SeqList相當於 struct SeqList 即可以通過SeqList L;直接聲明順序表變量

2.順序表的初始化

void InitList(SeqList *L)
{
    L->elem=(ElemType*)malloc(MAXSIZE*sizeof(ElemType));//分配空間,即最大的元素數量乘以每個元素佔的字節數。最後把指針類型強制轉換位該元素類型的。
    if(!L->elem)//內存分配失敗會返回NULL
        exit(OVERFLOW);//直接結束進程超量溢出,給系統返回錯誤代碼-2
    L->length=0; //把順序表的長度設置爲0
    L->ListSize=MAXSIZE;//把當前順序表的最大容量設置爲MAXSIZE
}

3.順序表的長度

int ListLength(SeqList L)
{
    return L.length;//返回線性表的的長度
}

4.判斷順序表是否爲空

//判斷線性表是否爲空
int ListEmpty(SeqList L)
{
    if(L.length==0)//如果長度爲0,返回1
        return 1;
    return 0;//默認非空,返回0;
}

5.打印出線性表的所有元素

//打印出線性表所有的元素
void PrintList(SeqList L)
{

    if(IsEmpty(L))
        printf("該順序表爲空表!\n");
    else
        for( int i=0; i<ListLength(L); i++)
        {
            printf("%d ",*(L.elem+i));
        }
}

6.向順序表的指定位置插入元素

int InsertList(SeqList *L,int pos,ElemType e)//pos 插入的位置 e 插入的元素
{
    int j;//作爲循環變量
    //先判斷插入的位置是否合法
    if(pos<1||pos>L->length+1)
    {
        printf("插入位置不合法!\n");
        return ERROR;
    }
    //判斷所剩空間是否充足,如果已滿則需擴充空間
    else if(L->length==L->ListSize)
    {
        ElemType *temp;//建立一個指針存儲返回的新的起始地址
        temp=realloc(L->elem,(L->ListSize+LISTCREMENT)*sizeof(ElemType));//realloc爲更改存儲空間大小的函數
        //判斷是否分配內存成功
        if(!temp)
        {
          printf("分配內存失敗!\n");
            exit(OVERFLOW);
        }
        else
        {
            L->elem=temp;
            L->ListSize+=LISTCREMENT;
        }
    }
    //從最後一個元素開始,向右平移一個單位,直到要插入的元素空出來
    else
    {
        for(j=L->length; j>=pos; j--)
            *(L->elem+j)=*(L->elem+j-1);//讓後一個元素等與前一個元素
        *(L->elem+pos-1)=e;
        L->length++;//表長加一
    }
    return OK;
}

7.刪除順序表指定位置的元素

int DeleteList(SeqList *L,int pos,ElemType *e)//用e來保存刪除位置的元素
{
    int i;//循環變量
    //判斷刪除的位置是否合理
    if(L->length==0)
    {
        printf("線性表是空表,不能進行刪除!\n");
        return 0;
    }
    else if(pos<1||pos>L->length)
    {
        printf("刪除位置不合理\n");
        return ERROR;
    }
    //從要刪除的位置的右邊開始,元素左移
    else
    {
        for(i=pos; i<L->length; i++)
            *(L->elem+i-1)=*(L->elem+i);

       L->length=L->length-1;
    }

    return OK;
}

8.摧毀順序表


int DestroyList(SeqList *L)
{
    free(L->elem);
    L->elem=0;//空指針
    L->length=0;
    L->ListSize=0;
    printf("順序表已銷燬!\n");
    return OK;
}

9.清空線性表

int ClearLIst(SeqList *L)
{
    if(L->length==0)
      {
           printf("順序表本來就是空表,不必清空!\n");
           return 0;
      }
      L->length=0;
    printf("順序表已清空!\n");
    return OK;
}

10.獲取順序表指定位置的值

ElemType GetElem(SeqList L,int pos)
{
    if(pos>L.length||pos<1)
    {
        printf("輸入的位置不合法!\n");
        return ERROR;
    }
    return *(L.elem+pos-1);
}

11.獲取指定元素的位置

int LocatElem(SeqList L,ElemType e)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        if(e==*(L.elem+i))
            return i+1;
    }
    printf("順序表中沒有該元素!\n");
    return FALSE;
}

12.求指定元素的前驅元素

ElemType ProElem(SeqList L,ElemType e)
{
    if(!LocatElem(L,e))
        printf("順序表中沒有該元素!\n");
        else
        {
            if(LocatElem(L,e)==1)
            {
                printf("該元素沒有前驅元素!\n");
                return ERROR;
            }

        }
        return *(L.elem+LocatElem(L,e)-1-1);
}

13.求指定元素的後繼元素

//求指定元素的後繼元素
ElemType NextElem(SeqList L,ElemType e)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        if(e==*(L.elem+i))
        {
            if(i==L.length-1)
            {
                printf("最後一個元素沒有後繼!\n");
                return ERROR;
            }
            return *(L.elem+i+1);
        }
    }
    printf("沒有該元素!\n");
    return FALSE;
}

完整代碼

SeqList.h

//聲明順序表的結構
typedef int ElemType; //元素的基本數據類型,方便更改
typedef struct //SeqList可以省略
{
    ElemType *elem;//定長數組;
    int length;//有效數字的個數,順序表當前存儲元素的個數;
    int ListSize;

} SeqList; //這裏的SeqList相當於 struct SeqList 即可以通過SeqList L;直接聲明順序表變量

//順序表的初始化
void InitList(SeqList *L)
{
    L->elem=(ElemType*)malloc(MAXSIZE*sizeof(ElemType));//分配空間,即最大的元素數量乘以每個元素佔的字節數。最後把指針類型強制轉換位該元素類型的。
    if(!L->elem)//內存分配失敗會返回NULL
        exit(OVERFLOW);//直接結束進程超量溢出,給系統返回錯誤代碼-2
    L->length=0; //把順序表的長度設置爲0
    L->ListSize=MAXSIZE;//把當前順序表的最大容量設置爲MAXSIZE
}
//判斷線性表是否爲空
int IsEmpty(SeqList L)
{
    if(L.length==0)
        return 1;
    return 0;
}
//順序表的長度
int ListLength(SeqList L)
{
    return L.length;//返回線性表的的長度
}
//打印出線性表所有的元素
void PrintList(SeqList L)
{

    if(IsEmpty(L))
        printf("該順序表爲空表!\n");
    else
        for( int i=0; i<ListLength(L); i++)
        {
            printf("%d ",*(L.elem+i));
        }
    printf("\n");
}
//向順序表的指定位置插入元素
int InsertList(SeqList *L,int pos,ElemType e)//pos 插入的位置 e 插入的元素
{
    int j;//作爲循環變量
    //先判斷插入的位置是否合法
    if(pos<1||pos>L->length+1)
    {
        printf("插入位置不合法!\n");
        return ERROR;
    }
    //判斷所剩空間是否充足,如果已滿則需擴充空間
    else if(L->length==L->ListSize)
    {
        ElemType *temp;//建立一個指針存儲返回的新的起始地址
        temp=realloc(L->elem,(L->ListSize+LISTCREMENT)*sizeof(ElemType));//realloc爲更改存儲空間大小的函數
        //判斷是否分配內存成功
        if(!temp)
        {
            printf("分配內存失敗!\n");
            exit(OVERFLOW);
        }
        else
        {
            L->elem=temp;
            L->ListSize+=LISTCREMENT;
        }
    }
    //從最後一個元素開始,向右平移一個單位,直到要插入的元素空出來
    for(j=L->length; j>=pos; j--)
        *(L->elem+j)=*(L->elem+j-1);//讓後一個元素等與前一個元素
    *(L->elem+pos-1)=e;
    ++L->length;//表長加一

    return OK;
}
//刪除指定位置的元素
int DeleteList(SeqList *L,int pos,ElemType *e)//用e來保存刪除位置的元素
{
    int i;//循環變量
    //判斷刪除的位置是否合理
    if(L->length==0)
    {
        printf("線性表是空表,不能進行刪除!\n");
        return 0;
    }
    else if(pos<1||pos>L->length)
    {
        printf("刪除位置不合理\n");
        return ERROR;
    }
    //從要刪除的位置的右邊開始,元素左移
    else
    {
        for(i=pos; i<L->length; i++)
            *(L->elem+i-1)=*(L->elem+i);

        L->length=L->length-1;
    }

    return OK;
}
//摧毀順序表
int DestroyList(SeqList *L)
{
    free(L->elem);
    L->elem=0;//空指針
    L->length=0;
    L->ListSize=0;
    printf("順序表已銷燬!\n");
    return OK;
}
//清空線性表
int ClearLIst(SeqList *L)
{
    if(L->length==0)
    {
        printf("順序表本來就是空表,不必清空!\n");
        return 0;
    }
    L->length=0;
    printf("順序表已清空!\n");
    return OK;
}
//獲取順序表指定位置的值
ElemType GetElem(SeqList L,int pos)
{
    if(pos>L.length||pos<1)
    {
        //printf("輸入的位置不合法!\n");
        return ERROR;
    }
    return *(L.elem+pos-1);
}
//獲取指定元素的位置
int LocatElem(SeqList L,ElemType e)
{
    int i;
    for(i=0; i<L.length; i++)
    {
        if(e==*(L.elem+i))
            return i+1;
    }
    printf("順序表中沒有該元素!\n");
    return FALSE;
}
//求指定元素的前驅
ElemType ProElem(SeqList L,ElemType e)
{
    if(!LocatElem(L,e))
        {printf("順序表中沒有該元素!\n");
         return ERROR;
        }
        else
        {
            if(LocatElem(L,e)==1)
            {
               // printf("該元素沒有前驅元素!\n");
                return ERROR;
            }

        }
        return *(L.elem+LocatElem(L,e)-1-1);
}
//求指定元素的後繼元素
ElemType NextElem(SeqList L,ElemType e)
{
    int i;
    for(i=0;i<L.length;i++)
    {
        if(e==*(L.elem+i))
        {
            if(i==L.length-1)
            {
                //printf("最後一個元素沒有後繼!\n");
                return ERROR;
            }
            return *(L.elem+i+1);//返回第i+1個元素
        }
    }
    printf("沒有該元素!\n");
    return FALSE;
}

main.c

//typedef int ElemType;
#define LISTCREMENT 10 //存儲空間增量,空間不足時便於增加
#define MAXSIZE 100
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define INFESAIBLE -1 //不能執行的
#define OVERFLOW -2
typedef int Status;// status是函數的類型,其值是函數結果狀態代碼
#include <stdio.h>
#include <stdlib.h>
#include "SqList.h" //包含順序表的操作函數
void Menu();
int main()
{
    int pos;//充當循環和其他變liang
    ElemType e;
    SeqList L;//聲明一個順序表L;
    InitList(&L);//初始化;
    int flag;
    Menu();
    while(1)
    {
        printf("請輸入你要進行的操作:");
        scanf("%d",&flag);
        getchar();
        switch(flag)
        {
        case 0:
            Menu();
            break;
        case 1:
            InitList(&L);
            break;
        case 2:
            printf("線性表的長度爲:%d\n",ListLength(L));
            break;
        case 3:
            if(IsEmpty(L))
                printf("線性表是空表!\n");
            else
                printf("線性表不是空表!\n");
            break;
        case 4:
            PrintList(L);
            break;
        case 5:
            printf("請輸入你要插入的位置和元素:");
            scanf("%d %d",&pos,&e);
            getchar();
            if(InsertList(&L,pos,e))
                printf("插入成功!\n");
            break;
        case 6:
            printf("請輸入你要刪除的位置:");
            scanf("%d",&pos);
            if(DeleteList(&L,pos,&e))
                printf("刪除成功,你刪除的元素是%d\n",e);
            break;
        case 7:
            DestroyList(&L);
            break;
        case 8:
            ClearLIst(&L);
            break;
        case 9:
            printf("請輸入你要查詢的位置:");
            scanf("%d",&pos);
            getchar();
            if(GetElem(L,pos))
                printf("第%d個元素爲%d\n",pos,GetElem(L,pos));
            else
                printf("輸入的位置不合法!\n");
            break;
        case 10:
            printf("請輸入你要查詢的元素:");
            scanf("%d",&e);
            getchar();
            if(LocatElem(L,e))
                printf("元素%d的位置爲%d\n",e,LocatElem(L,e));
            else
                printf("順序表中沒有該元素!\n");
            break;
        case 11:
            printf("請輸入你要查詢的元素:");
            scanf("%d",&e);
            getchar();
            if(ProElem(L,e))
                printf("元素%d的前驅爲%d\n",e,ProElem(L,e));
            else
                printf("該元素沒有前驅元素!\n");
            break;
        case 12:
            printf("請輸入你要查詢的元素:");
            scanf("%d",&e);
            getchar();
            if(NextElem(L,e))
                printf("元素%d的後繼爲%d\n",e,NextElem(L,e));
            else
                printf("該元素沒有後繼元素!\n");
            break;
        default :
            if(flag<0)
                exit(0);
            else
                printf("你輸入的數字不合法!\n");
            break;

        }
    }
    return 0;
}
void Menu()
{
    printf("          順序表的基本操作           \n");
    printf("  0.打印出菜單\n");
    printf("  1.初始化順序表\n");
    printf("  2.求出當前順序表的長度\n");
    printf("  3.判斷順序表是否爲空\n");
    printf("  4.打印出順序表中的所有元素\n");
    printf("  5.向順序表的指定位置插入元素\n");
    printf("  6.刪除順序表的指定位置的元素\n");
    printf("  7.摧毀順序表\n");
    printf("  8.清空順序表\n");
    printf("  9.獲取順序表指定位置的值\n");
    printf("  10.獲取順序表指定值的位置\n");
    printf("  11.獲取順序表指定值的前驅\n");
    printf("  12.獲取順序表指定值的後繼\n");
    printf(" !!!請輸入一個負數退出此程序!\n");

}

最終運行結果

          順序表的基本操作
  0.打印出菜單
  1.初始化順序表
  2.求出當前順序表的長度
  3.判斷順序表是否爲空
  4.打印出順序表中的所有元素
  5.向順序表的指定位置插入元素
  6.刪除順序表的指定位置的元素
  7.摧毀順序表
  8.清空順序表
  9.獲取順序表指定位置的值
  10.獲取順序表指定值的位置
  11.獲取順序表指定值的前驅
  12.獲取順序表指定值的後繼
 !!!請輸入一個負數退出此程序!
請輸入你要進行的操作:0
          順序表的基本操作
  0.打印出菜單
  1.初始化順序表
  2.求出當前順序表的長度
  3.判斷順序表是否爲空
  4.打印出順序表中的所有元素
  5.向順序表的指定位置插入元素
  6.刪除順序表的指定位置的元素
  7.摧毀順序表
  8.清空順序表
  9.獲取順序表指定位置的值
  10.獲取順序表指定值的位置
  11.獲取順序表指定值的前驅
  12.獲取順序表指定值的後繼
 !!!請輸入一個負數退出此程序!
請輸入你要進行的操作:1
請輸入你要進行的操作:2
線性表的長度爲:0
請輸入你要進行的操作:3
線性表是空表!
請輸入你要進行的操作:4
該順序表爲空表!

請輸入你要進行的操作:5
請輸入你要插入的位置和元素:1 1
插入成功!
請輸入你要進行的操作:5
請輸入你要插入的位置和元素:2 2
插入成功!
請輸入你要進行的操作:5
請輸入你要插入的位置和元素:3 3
插入成功!
請輸入你要進行的操作:4
1 2 3
請輸入你要進行的操作:9
請輸入你要查詢的位置:1
第1個元素爲1
請輸入你要進行的操作:9
請輸入你要查詢的位置:2
第2個元素爲2
請輸入你要進行的操作:10
請輸入你要查詢的元素:2
元素2的位置爲2
請輸入你要進行的操作:10
請輸入你要查詢的元素:1
元素1的位置爲1
請輸入你要進行的操作:11
請輸入你要查詢的元素:2
元素2的前驅爲1
請輸入你要進行的操作:12
請輸入你要查詢的元素:3
該元素沒有後繼元素!
請輸入你要進行的操作:8
順序表已清空!
請輸入你要進行的操作:-1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章