順序表的操作(動態)
靜態定義一個順序表,是通過數組來定義, 順序表所佔的內存空間開闢在內存的棧上, 隨着函數調用的結束, 這塊內存區域會被系統自動回收;
而動態定義順序表, 順序表所佔的內存空間開闢在內存的堆上, 這塊區域不會隨着函數調用的結束被系統自動回收, 而是需要程序員自己去釋放它。
順序表的基本操作
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