1. 程式人生 > >資料結構C語言實現——順序線性表SqList

資料結構C語言實現——順序線性表SqList

delcaration.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.h
#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
#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()
         function.c中的LocateElem_Sq()及ListTraverse_Sq()函式的操作中涉及到函式指標的內容。不太熟悉的童鞋可以參見C語言基礎知識----指標陣列 && 陣列指標 && 函式指標 &&指標函式

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;
}
執行結果