資料結構C語言實現——順序線性表SqList
阿新 • • 發佈:2019-02-02
delcaration.h
function.h#ifndef DECLARATION_H_INCLUDED #define DECLARATION_H_INCLUDED #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define ElemType int typedef int Status; #define LIST_INIT_SIZE 100 //線性表儲存空間的初始分配量 #define LISTINCREMENT 10 //線性表儲存空間的分配增量 typedef struct { ElemType *elem; //儲存空間基址 int length; //當前長度 int listsize; //當前分配的儲存容量(以sizeof(ElemType)為單位) }SqList; #endif // DECLARATION_H_INCLUDED
function.c#ifndef FUNCTION_H_INCLUDED #define FUNCTION_H_INCLUDED Status InitList_Sq(SqList *L); //構造一個空的線性表L Status DestroyList_Sq(SqList *L); //初始條件:線性表已存在;操作結果:銷燬線性表L Status ClearList_Sq(SqList *L); //初始條件:線性表已存在;操作結果:將線性表L置為空表 Status ListEmpty_Sq(SqList L); //初始條件:線性表已存在;操作結果:若L為空表則返回TRUE否則返回ERROR Status ListLength_Sq(SqList L); //初始條件:線性表已存在;操作結果:返回L中元素的個數 Status GetElem_Sq(SqList L, int i, ElemType *e); //初始條件:線性表已存在,1<=i<=ListLength_Sq(L);操作結果:用e返回L中第i個元素的值 Status LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType)); //初始條件:線性表已存在,compare()是資料元素判定函式; //操作結果:返回L中第1個與e滿足compare()關係的資料元素的位序。若這樣的數不存在則返回值為0。 Status PriorElem_Sq(SqList L, ElemType cur_e, ElemType * pre_e); //初始條件:線性表L已存在 //操作結果:若cur_e是L的元素,且不是第一個,則用pre_e返回它的前驅。否則操作失敗,pre_e無定義 Status NextElem_Sq(SqList L, ElemType cur_e, ElemType *next_e); //初始條件:線性表L已存在 //操作結果:若cur_e是L的資料,且不是最後一個,則用next_e返回它的後繼。否則操作失敗,next_e無定義 Status ListInsert_Sq(SqList *L, ElemType i, ElemType e); //初始條件:線性表你已存在,1<=i<=ListLength_Sq(L)+1 //操作結果:在L中第i個位置之前插入新的資料元素e,L的長度加1 Status ListDelete_Sq(SqList *L, ElemType i, ElemType *e); //初始條件:線性表你已存在,1<=i<=ListLength_Sq(L)+1 //操作結果:刪除L中第i個數據元素,並用e返回其值,L的長度減1 Status ListTraverse_Sq(SqList L, void (*visit) (void const *)); //初始條件:線性表 L已存在 //操作結果:依次對L的每個資料元素呼叫visit()函式。一旦visit()失敗,則操作失敗 void visit_print(void const *e); //輸出地址e所指向記憶體的值 void Union_Sq(SqList *La, SqList Lb); //將存在於Lb中而不在La中的資料插入到La中去 Status compare_Elem(ElemType a, ElemType b); //比較a,b的大小,若相等則返回1,否則返回0 void MergeList_Sq(SqList *La, SqList Lb,SqList *Lc); //初始條件:已知順序線性表La和Lb的元素按值非遞減排列 //操作結果:歸併La和Lb得到新的線性表Lc,Lc的元素也按值非遞減排列 #endif // FUNCTION_H_INCLUDED
function.c中的LocateElem_Sq()及ListTraverse_Sq()函式的操作中涉及到函式指標的內容。不太熟悉的童鞋可以參見C語言基礎知識----指標陣列 && 陣列指標 && 函式指標 &&指標函式#include <stdio.h> #include <stdlib.h> #include "declaration.h" Status compare_Elem(ElemType a, ElemType b) { if(a == b) return 1;// 若相等返回1 else return 0; } void visit_print(void const *e) { printf("%d ",*(int *)e); } Status InitList_Sq(SqList *L) { //構造空線性表L L->elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(!L->elem) exit(OVERFLOW); L->length=0; L->listsize=LIST_INIT_SIZE; //線性表L的初始容量 return OK; }//InitList_Sq Status DestroyList_Sq(SqList *L) { //銷燬線性表L free(L->elem); L->elem=NULL; L->length=0; L->listsize=0; return OK; }//DestroyList_Sq() Status ClearList_Sq(SqList *L) { //將L置為空表 L->length=0; return OK; }//ClearList_Sq() Status ListEmpty_Sq(SqList L) { //判斷是否為空表 if(L.length == 0) return TRUE; else return ERROR; }//ListEmpty_Sq() Status ListLength_Sq(SqList L) { //返回線性表的長度 return L.length; }//ListLength_Sq() Status GetElem_Sq(SqList L, int i, ElemType *e) { //用e返回L中第i個元素的值 *e=*(L.elem+i-1); return *e; }//GetElem_Sq() Status LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType , ElemType)) { //線上性表中找到第1個與e滿足compare()關係的元素的位序 ElemType *p; int i=1; p=L.elem; while(i <= L.length && !(*compare)(*p++, e)) i++; if(i < L.length) return i; //返回位置 else return 0; }//LocateElem_Sq() Status PriorElem_Sq(SqList L, ElemType cur_e, ElemType * pre_e) { //若cur_e是L的元素,且不是第一個,則用pre_e返回它的前驅。否則操作失敗,pre_e無定義 ElemType *p,i=1; p=L.elem; if(*(L.elem) == cur_e) { printf("%d is the first place has no PreElem", cur_e); return INFEASIBLE; } else { while(*p != cur_e) p += i++; if(i> 0 && i < L.length) { *pre_e=*(p-1); return *pre_e; } else { return INFEASIBLE; } } }//PriorElem_Sq() Status NextElem_Sq(SqList L, ElemType cur_e, ElemType *next_e) { ElemType *p,i=1; p=L.elem; while( *p != cur_e) p+= i++; if(p == L.elem+L.length-1) { printf("%d is the last letter has no next_elem\n", cur_e); return INFEASIBLE; } else return *next_e=*(p+1); }//NextElem_Sq() Status ListInsert_Sq(SqList *L, ElemType i, ElemType e) //i從1開始 { //i的合法值為1<=i<=ListLength_Sq(L)+1 ElemType *newbase,*q,*p; if(i <1 || i>L->length+1) //L->length初始為0 return ERROR; if(L->length >= L->listsize) { newbase=(ElemType *) realloc(L->elem, (L->listsize+LISTINCREMENT) *sizeof(ElemType)); if(!newbase) exit(OVERFLOW); L->elem = newbase; //新基址 L->listsize += LISTINCREMENT; //增加儲存容量 } q=L->elem+i-1; // q為插入位置 for(p=(*L).elem+(*L).length-1;p>=q;--p) /* 插入位置及之後的元素右移 */ *(p+1)=*p; *q=e; /* 插入e */ ++(*L).length; /* 表長增1 */ return OK; }//ListInsert_Sq() Status ListDelete_Sq(SqList *L, ElemType i, ElemType *e) { //刪除L中第i個數據元素,並用e返回其值,L的長度減1 ElemType *q,*p; if(i <1 || i>L->length) return ERROR; p=L->elem+L->length-1; q=L->elem+i-1; // q為刪除位置 for(q; q < p; q++) /* 刪除位置及之後的元素左移 */ *q=*(q+1); --(*L).length; /* 表長減1 */ return OK; }//ListDelete_Sq() Status ListTraverse_Sq(SqList L, void (*visit)( void const *)) { //操作結果:依次對L的每個資料元素呼叫visit()函式。一旦visit()失敗,則操作失敗 ElemType *ptr; ptr=L.elem; ElemType i=0; for(i=0 ;i < L.length;i++) visit(ptr+i); printf("\n"); return OK; }//ListTraverse_Sq() void Union_Sq(SqList *La, SqList Lb) { ElemType la_ln,lb_ln,e; la_ln=ListLength_Sq(*La); lb_ln=ListLength_Sq(Lb); ElemType i=1; for( i; i <= lb_ln; i++) { GetElem_Sq(Lb, i, &e); //用e取得Lb中的資料 if( !LocateElem_Sq(*La, e, compare_Elem)) ListInsert_Sq(La, ++la_ln,e); // 若不存在這樣的數,就在La的結尾新增這個數 } }//Union_Sq() void MergeList_Sq(SqList *La, SqList Lb,SqList *Lc) { //將La和Lb中的元素按遞增關係合併到Lc中 ElemType *pa, *pb, *pc, *pa_last, *pb_last; pa=La->elem; pb=Lb.elem; Lc->listsize = Lc->length=La->length+Lb.length; pc=Lc->elem=(ElemType *)malloc(Lc->listsize*sizeof(ElemType)); if(!pc) exit(OVERFLOW);//儲存分配失敗 pa_last=La->elem+La->length-1; pb_last=Lb.elem+Lb.length-1; while((pa <= pa_last) && (pb <= pb_last)) //La和Lb均非空 { if(*pa <= *pb) *pc++ = *pa++; else *pc++ = *pb++; } while(pa <= pa_last) *pc ++ = *pa ++; //插入La剩餘的元素 while(pb <= pb_last) *pc ++= *pb ++; //插入Lb剩餘的元素 }//MergeList_Sq()
main.c
#include <stdio.h>
#include <stdlib.h>
#include "declaration.h"
#include "function.h"
int main()
{
SqList La,Lb,Lc;
Status i,e;
int j;
i=InitList_Sq(&La);
if(i==1) /* 建立空表La成功 */
{
printf("La create success\n");
for(j=1;j<=5;j++) /* 在表La中插入5個元素 */
ListInsert_Sq(&La,j,j);
}
printf("La= "); /* 輸出表La的內容 */
ListTraverse_Sq(La, visit_print);
InitList_Sq(&Lb); /* 也可不判斷是否建立成功 */
for(j=1;j<=5;j++) /* 在表Lb中插入5個元素 */
ListInsert_Sq(&Lb,j,2*j);
printf("Lb= "); /* 輸出表Lb的內容 */
ListTraverse_Sq(Lb,visit_print);
printf("Lb.length is %d\n",ListLength_Sq(Lb));
i= LocateElem_Sq(Lb, 2, compare_Elem);
printf("Lb中與2相等的數在第%d個位置\n",i);
printf("La表中第%d個位置的數是%d\n", 3, GetElem_Sq(La, 3, &e));
printf("La表中2前驅是%d\n", PriorElem_Sq(La, 2, &e));
printf("La表中2的後繼是%d\n", NextElem_Sq(La, 2, &e));
printf("\n\n");
printf("MergeList function:");
MergeList_Sq(&La,Lb, &Lc);
printf("Lc= "); /* 輸出新表La的內容 */
ListTraverse_Sq(Lc,visit_print);
printf("Union function:");
Union_Sq(&La,Lb);
printf("new La= "); /* 輸出新表La的內容 */
ListTraverse_Sq(La,visit_print);
if(ListDelete_Sq(&La,3, &e) == OK)
{
printf("after delete La = ");
ListTraverse_Sq(La, visit_print);
}
return 0;
}
執行結果