線性表插入和刪除——程式例項
阿新 • • 發佈:2019-02-18
順序實現
.h檔案 此檔案為方法 #ifndef SQLIST_H_INCLUDED #define SQLIST_H_INCLUDED #include "ds.h" //for Status,OK ... #ifndef ElemType #define ElemType int /* 資料元素型別預設為 int */ #define ELEMTYPE_TAG #endif /********************************************************** * 順序表的儲存結構定義 ***********************************************************/ #define LIST_INIT_SIZE 100 /* 儲存空間初始分配容量 */ #define LISTINCREMENT 10 /* 儲存空間分配的增量 */ typedef struct { ElemType *elem; //儲存空間基址 int length; //當前長度 int listsize; //當前已分配的儲存空間(元素個數) } SqList; /********************************************************** * 順序表的基本操作宣告 ***********************************************************/ //建立並初始化為空表 Status InitList(SqList &L); //銷燬整個表(從此之後不再可用) Status DestroyList(SqList &L); //將表L置空 Status ClearList(SqList &L); //判斷表L是否為空表 bool ListEmpty(SqList L); //求表L的長度 int ListLength(SqList L); //取表L中的第i個元素,並用e返回. 操作成功返回OK,失敗時返回ERROR Status GetElem(SqList L, int i, ElemType &e); template <typename T> bool equal(T a, T b) { return a==b; } //在表L中定位元素e首次出現的位置. 操作成功返回位序,失敗時返回0 // compare(a,b) 為比較函式,匹配時返回true,否則返回false // 這裡預設使用equal進行比較 int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType,ElemType)=equal<ElemType>); //在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR Status ListInsert(SqList &L, int i, ElemType e); //刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR Status ListDelete(SqList &L, int i, ElemType &e); //遍歷表L,對每個元素呼叫visit(x). Status ListTraverse(SqList L, Status (*visit)(ElemType)); /********************************************************** * 順序表的基本操作的實現 ***********************************************************/ //建立並初始化為空表 Status InitList(SqList &L) { // TODO (#1#): 建立空表 L.elem=(ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if(!L.elem)exit(OVERFLOW); L.length=0; L.listsize=LIST_INIT_SIZE; return OK; //------------------------------------- } //銷燬整個表(從此之後不再可用) Status DestroyList(SqList &L) { free(L.elem); return OK; //------------------------------------- } //將表L置空 Status ClearList(SqList &L) { // TODO (#1#): 清空表 L.length=0; return OK; //------------------------------------- } //判斷表L是否為空表 bool ListEmpty(SqList L) { // TODO (#1#): 順序表判空 if(L.length==0) return TRUE; else return FALSE; //------------------------------------- } //求表L的長度 int ListLength(SqList L) { // TODO (#1#): 求順序表長度 return L.length; //------------------------------------- } //取表L中的第i個元素,並用e返回. 操作成功返回OK,失敗時返回ERROR Status GetElem(SqList L, int i, ElemType &e) { // TODO (#1#): 取元素 if(ListEmpty(L)) { printf("線性表L為空n"); return ERROR; } if(i<1||i>L.length) { printf("不存在%d位置的元素n",i); return ERROR; } e=L.elem[i-1]; return OK; //------------------------------------- } //在表L中定位元素e首次出現的位置. 操作成功返回位序,失敗時返回0 // compare(a,b) 為比較函式,匹配時返回true,否則返回false int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType,ElemType)) { // TODO (#1#): 在表中定位元素e,用compare(a,b)匹配元素 for (int j=0; j<L.length; j++) if ( compare(L.elem[j],e) ) return j+1; return 0; //------------------------------------- } //在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR Status ListInsert(SqList &L, int i, ElemType e) { // TODO (#1#): 在連結串列中插入元素 if(i<1 || i>L.length+1) return ERROR; if (L.length >= L.listsize) //判讀儲存空間是否已滿 { ElemType * newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType)); if (!newbase) exit(OVERFLOW); L.elem = newbase; LL.listsize = L.listsize + LISTINCREMENT; } ElemType *q = &(L.elem[i - 1]); //q指向第i個元素 ElemType *p; //p指向最後一個元素 for (p= &(L.elem[L.length - 1]); p >= q; p--) //從最後一個位置開始移動 { *(p + 1) = *p; } *q = e; L.length++; return ERROR; //------------------------------------- } //刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR Status ListDelete(SqList &L, int i, ElemType &e) { // TODO (#1#): 在順序表中刪除元素 if (L.length == 0) //判斷表是否為空 { printf("表為空n"); return ERROR; } if (i < 1 || i > L.length) //判斷刪除位置是否合法 { printf("刪除位置不合法n"); return ERROR; } ElemType *p = &(L.elem[i - 1]); //p指向待刪除的元素 e = *p; ElemType *q = &(L.elem[L.length - 1]); //ElemType *q = L->elem + L->length - 1; //q指向最後一個元素 for (pp = p + 1; p <= q; p++) //p從待刪除的後一個元素開始,直到最後一個元素,每個元素一次向前移動一個位置 { *(p - 1) = *p; } L.length--; //最後,線性表長度減一 return OK; //------------------------------------- } //遍歷表L,對每個元素呼叫visit(x). Status ListTraverse(SqList L, Status (*visit)(ElemType)) { // TODO (#1#): 遍歷順序表 for (int j=0; j<L.length; j++) if ( ! visit(L.elem[j]) ) return ERROR; return OK; //------------------------------------- } .cpp檔案 此檔案為主函式 #ifdef ELEMTYPE_TAG #undef ElemType #undef ELEMTYPE_TAG #endif #endif // SQLIST_H_INCLUDED #include <stdio.h> #include <stdlib.h> #include "ds.h" #define ElemType int //資料元素的型別 Status print(ElemType e); // 列印資料元素的方法 bool equal(ElemType a, ElemType b); //比較兩個元素相等的方法 #include "sqlist.h" //列印順序表內容 void PrintLinkList(SqList L); int main() { SqList L; //1)初始化順序表 InitList(L); //2)插入一些元素: 12,23,34,45 ListInsert(L,1,12); ListInsert(L,1,23); ListInsert(L,1,34); ListInsert(L,1,45); //3)列印順序表資訊 printf("n開始時順序表內容n"); PrintLinkList(L); printf("ListLength(L) : %dn", ListLength(L)); printf("ListEmpty(L) : %dn", ListEmpty(L)); //4)順序表插入 printf("n請輸入一個元素:"); ElemType x; read(x); printf("插入開頭:"); ListInsert(L,1,x); PrintLinkList(L); printf("插入末尾:"); ListInsert(L,ListLength(L)+1,x); PrintLinkList(L); //5)順序表刪除 printf("n請選擇刪除第i(1..%d)個元素:", ListLength(L)); int i; read(i); ElemType e; if ( ListDelete(L,i,e)==OK ) { Status print(ElemType e); //宣告print(e)函式 printf("刪除"); print(e); printf("成功n"); } else printf("刪除失敗.n"); printf("順序表內容:"); PrintLinkList(L); //6)元素定位 printf("n請輸入一個元素以便定位:"); read(x); i = LocateElem(L,x); if ( i!=0 ) { printf("該元素是表中的第%d個元素.n",i); } else printf("該元素在表中不存在.n"); //7)清空順序表 ClearList(L); printf("n最後順序表內容n"); PrintLinkList(L); printf("ListLength(L) : %dn", ListLength(L)); printf("ListEmpty(L) : %dn", ListEmpty(L)); //8)銷燬順序表 DestroyList(L); system("PAUSE"); return 0; } // 列印資料元素的方法 Status print(ElemType e) { printf("%5d",e); return OK; } //比較兩個元素相等的方法 bool equal(ElemType a, ElemType b) { return a==b; } //列印順序表內容 void PrintLinkList(SqList L) { ListTraverse(L,print); //遍歷順序表並print()每個元素 printf("n"); }