資料結構——線性表的順序表示和實現(c語言)
阿新 • • 發佈:2019-02-20
PS:資料結構(C語言版)——清華大學出版社, 2.1節程式碼實現
#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define LIST_INIT_SIZE 100 //順序表初始分配空間 #define LISTINCREMENT 10 //順序表儲存空間分配增量 //Status是函式的型別,其值是函式結果狀態碼 typedef int Status; typedef int ElemType; //順序表儲存元素型別, 考慮到可移植性, 若改變儲存型別, 只需修改這一處,比較方便 typedef struct { ElemType *elem; //儲存空間地址 int length; //當前長度 int listsize; //當前分配的儲存容量(以sizeof(ElemType)為單位) }SqList; void Init_Sq(SqList *L); Status Insert_Sq(SqList *L, int i, ElemType e); Status Destroy_Sq(SqList *L); Status Delete_List(SqList *L, int i); void Travse_Sq(SqList *L); ElemType Next_Elem(SqList *L, int cur_elem); ElemType Prior_Elem(SqList *L, int cur_elem); ElemType GetElem(SqList *L, int i); int LocateElem_Sq(SqList *L, ElemType e); Status compare(ElemType e1, ElemType e2); int ListLength(SqList *L); void union_Sq(SqList *La, SqList *Lb); void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc); void main() { /*SqList L; int i; Init_Sq(&L); if( Insert_Sq(&L, 1, 4)) { printf("The element is %d\n", GetElem(&L, 1)); } if( Insert_Sq(&L, 2, 5)) { printf("The element is %d\n", GetElem(&L, 2)); } if( Insert_Sq(&L, 3, 6)) { printf("The element is %d\n", GetElem(&L, 3)); } if( Insert_Sq(&L, 4, 8)) { printf("The element is %d\n", GetElem(&L, 4)); } if( Insert_Sq(&L, 5, 18)) { printf("The element is %d\n", GetElem(&L, 5)); } Travse_Sq(&L); printf("Current number: "); scanf("%d", &i); printf("The prior of No.%d is %d\n", i, Prior_Elem(&L, i)); if(Delete_List(&L,1)) { printf("After delete:\n"); Travse_Sq(&L); } */ SqList La; SqList Lb; SqList Lc; Init_Sq(&La); Init_Sq(&Lb); if( Insert_Sq(&La, 1, 4)) { printf("The element in La is %d\n", GetElem(&La, 1)); } if( Insert_Sq(&La, 2, 5)) { printf("The element in La is %d\n", GetElem(&La, 2)); } if( Insert_Sq(&La, 3, 6)) { printf("The element in La is %d\n", GetElem(&La, 3)); } if( Insert_Sq(&La, 4, 8)) { printf("The element in La is %d\n", GetElem(&La, 4)); } if( Insert_Sq(&La, 5, 18)) { printf("The element in La is %d\n", GetElem(&La, 5)); } printf("\n"); if( Insert_Sq(&Lb, 1, 4)) { printf("The element in Lb is %d\n", GetElem(&Lb, 1)); } if( Insert_Sq(&Lb, 2, 15)) { printf("The element in Lb is %d\n", GetElem(&Lb, 2)); } printf("\n"); //union_Sq(&La, &Lb); // printf("After unite La and Lb:\n"); // Travse_Sq(&La); Merge_Sq(&La, &Lb, &Lc); printf("After merge La and Lb:\n"); Travse_Sq(&Lc); Destroy_Sq(&La); Destroy_Sq(&Lb); Destroy_Sq(&Lc); } void Init_Sq(SqList *L) { L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if(L->elem == NULL) { printf("Memory allocation is error!"); exit(1); //0表示正常退出,非零表示異常退出 } L->length = 0; L->listsize = LIST_INIT_SIZE; } //在第i個位置插入元素e Status Insert_Sq(SqList *L, int i, ElemType e) { ElemType *newbase; //指向新增順序表後的起始位置 ElemType *p; ElemType *q; if(i < 1 || i > L->length + 1) { printf("The location that inserted is illegal!\n"); return TRUE; } if(!(L->length < L->listsize)) //如果順序表滿了就擴充 newbase = (ElemType *)realloc(&L->elem, (L->length + LISTINCREMENT) * sizeof(ElemType)); p = &L->elem[i-1]; for(q = &L->elem[L->length - 1]; p <= q; q--) { *(q + 1) = *q; } *p = e; L->length ++; return TRUE; } //銷燬順序表 Status Destroy_Sq(SqList *L) { if(L->length < 1) return FALSE; free(L->elem); L->elem = NULL; return TRUE; } //刪除順序表中指定元素 Status Delete_List(SqList *L, int i) { ElemType *p; int j; if(i < 1 && i > L->length) { printf("The site that store element is not exist!\n"); return FALSE; } p = &L->elem[i - 1]; //初始使p指向將要刪除的位置 for(j = i - 1; j < L->length - 1; j++) { *p = *(p+1); p++; } L->length --; return TRUE; } //遍歷順序表 void Travse_Sq(SqList *L) { int i; if(L->length == 0) { printf("The sequence list is empty!\n"); } else for(i = 0; i < L->length; i++) printf("The No.%d is %d.\n", i, L->elem[i]); } //返回第i個數據 ElemType GetElem(SqList *L, int i) { if(i < 1 || i > L->length) return ERROR; return L->elem[i - 1]; } //返回第cur_elem個元素的直接前驅 ElemType Prior_Elem(SqList *L, int cur_elem) { if(cur_elem == 1) return ERROR; else return L->elem[cur_elem - 2]; } //返回第cur_elem個元素的直接後繼 ElemType Next_Elem(SqList *L, int cur_elem) { if(cur_elem == (L->length - 1)) return FALSE; else return L->elem[cur_elem]; } //記錄線性表的長度 int ListLength(SqList *L) { if(L->length == 0) { printf("The sequence list is empty!\n"); return 0; } else return L->length; } //線性表A和B作並集操作 void union_Sq(SqList *La, SqList *Lb) { //將所有線上性表Lb中但不在La中的資料元素插入到La中 int La_len, Lb_len; int i; int Lb_cur_elem; //記錄Lb中取出的元素 La_len = ListLength(La); Lb_len = ListLength(Lb); //注意,取的是第i個元素,是從人們熟悉的1開始計數 //GetElem()函式中會做減1處理(計算機的計數方式) for(i = 1; i <= Lb_len; i++) { Lb_cur_elem = GetElem(Lb, i); if(!LocateElem_Sq(La, Lb_cur_elem)) Insert_Sq(La, ++La_len, Lb_cur_elem); } } Status compare(ElemType e1, ElemType e2) { if(e1 == e2) return TRUE; else return FALSE; } //在順序線性表L中查詢第一個值與e滿足compare()的元素的位序 //若找到,則返回其在L中的位序,否則返回0 int LocateElem_Sq(SqList *L, ElemType e) { int i; ElemType *p; i = 1; //i的初值為第一個元素的位序 p = L->elem; //p的初值為第1個元素的儲存位置 while(i <= L->length && (e != *p++)) i++; if(i <= L->length) return i; else return 0; } //已知順序線性表La,和Lb的元素按值非減排列 //歸併La和Lb得到新的順序線性表Lc,Lc的元素也是按值非減排列 void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc) { ElemType *pa; ElemType *pb; ElemType *pc; ElemType *pa_last; ElemType *pb_last; //給Lc的elem元素分配空間 Lc->elem = (ElemType *)malloc((La->length + Lb->length) * sizeof(ElemType)); if(!Lc->elem) { printf("Error!\n"); exit(1); } pa = La->elem; //pa指向La的第一個元素 pb = Lb->elem; //pb指向Lb的第一個元素 pc = Lc->elem; //pc指向Lc的首地址 Lc->length = La->length + Lb->length; pa_last = &La->elem[La->length - 1]; //指向La的最後一個元素(La中的最大的元素) pb_last = &Lb->elem[Lb->length - 1]; //指向Lb的最後一個元素(Lb中的最大的元素) while(pa <= pa_last && pb <= pb_last) //實現歸併 { if(*pa <= *pb) { *pc++ = *pa++; } else *pc++ = *pb++; } while(pa <= pa_last) *pc++ = *pa++; while(pb <= pb_last) *pc++ = *pb++; }