《數據結構》---線性表的順序表示與實現

本程序在CodeBlocks運行通過,博客結尾附有下載鏈接。
在main.c中需要調用func2-2.h頭文件。
注:由於在main.c中要打印一些特殊類型的數據,爲了不頻繁使用printf()函數,所以在func2-2.h中定了了一些print()用戶自定義函數,方便進行數據的比較與打印等等操作。

func2-2.h

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;

Status equal(ElemType e1,ElemType e2)
{//判斷是否相等函數
    if(e1 == e2)
        return OK;
    else
        return FALSE;
}

int com(ElemType e1,ElemType e2)//返回值是int型
{//根據a<、=或>b,分別返回-1、0或1
    if(e1 == e2)
        return 0;
    else
        return (e1 - e2)/ (abs(e1 - e2));
}

void print(ElemType e)
{//以十進制整型的格式輸出元素的值
    printf("%d",e);
}

void print1(ElemType &e)
{//以十進制整型的格式輸出元素的值(設C爲引用類型)
    printf("%d ",e);
}

void print2(ElemType e)
{//以字符型的格式輸出元素的值
    printf("%c",e);
}

main.c

#include <stdio.h>
#include <malloc.h>
#include "func2-2.h"
#include <stdlib.h>
typedef int Status;
typedef int ElemType;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define LIST_INIT_SIZE 100
#define LIST_INCREMENT 10
#define N 10

typedef struct
{
    ElemType *elem;//elem爲指針變量,存儲的是順序表L的基地址
    int length;
    int listsize;
}Sqlist;

//func2-2函數調用聲明
void print1(ElemType &e);
Status equal(ElemType e1,ElemType e2);

//本文件函數聲明

void InitSqlist_Sq(Sqlist &L);
void Destroy_Sq(Sqlist &L);
void Clear_Sq(Sqlist &L);
Status ListEmpty_Sq(Sqlist L);
int ListLength_Sq(Sqlist L);
Status GetElem_Sq(Sqlist L,int i,ElemType &e);
int Locate_Sq(Sqlist L,ElemType e,Status (* compare)(ElemType,ElemType));//compare()函數
Status PriorElem_Sq(Sqlist L,ElemType cur_e,ElemType &pre_e);
Status NextElem_Sq(Sqlist L,ElemType cur_e,ElemType &next_e);
Status ListInsert_Sq(Sqlist &L,int i,ElemType e);
Status ListDelete_Sq(Sqlist &L,int i,ElemType &e);
Status ListTraverse_Sq(Sqlist L,void(* visit)(ElemType &e));

//主函數
int main()
{
    Sqlist L;
    int e,e1,i,j,k,m,pre_e,next_e,ins_e,del_e;
    //Status flag;
    InitSqlist_Sq(L);
    printf("初始化L表後,L.length = %d, L.listsize = %d, L.elem = %p\n",L.length,L.listsize,L.elem);//%p用於輸出L.elem在內存中的地址
    for(i = 1; i <= N; i++)
        ListInsert_Sq(L,1,i);
    printf("L表中的元素爲:");
    ListTraverse_Sq(L,print1);

    printf("請輸入需要查詢L表中第j個元素(1<=j<=%d):",L.length);
    scanf("%d",&j);
    while(j<1 || j>L.length)
    {
        printf("超出範圍!請重新輸入!\n");
        printf("請輸入需要查詢L表中第j個元素(1<=j<=%d):",L.length);
        scanf("%d",&j);
    }
    GetElem_Sq(L,j,e);
    printf("L表中第%d個元素的值爲:%d\n",j,e);

    printf("查詢L表中第幾個元素的前一個元素[2,%d]:",L.length);
    scanf("%d",&j);
    while(j<2 || j>L.length)
    {
        printf("超出範圍!請重新輸入!\n");
        printf("查詢L表中第幾個元素的前一個元素[2,%d]:",L.length);
        scanf("%d",&j);
    }
    GetElem_Sq(L,j,e);
    PriorElem_Sq(L,e,pre_e);
    printf("第%d個元素爲%d,它的前一個元素是:%d\n",j,e,pre_e);

    printf("查詢L表中第幾個元素的後一個元素[1,%d]:",L.length-1);
    scanf("%d",&j);
    while(j<1 || j>L.length-1)
    {
        printf("超出範圍!請重新輸入!\n");
        printf("查詢L表中第幾個元素的後一個元素[1,%d]:",L.length-1);
        scanf("%d",&j);
    }
    GetElem_Sq(L,j,e);
    NextElem_Sq(L,e,next_e);
    printf("第%d個元素爲%d,它的後一個元素是:%d\n",j,e,next_e);

    printf("請輸入想要在L中匹配的數:",e1);
    scanf("%d",&e1);
    k = Locate_Sq(L,e1,equal);
    if(k)//k不爲零,說明L中存在與e1匹配的數
        printf("第%d個數與%d匹配!\n",k,e1);
    else//否則說明不存在與e1匹配的數
        printf("L中不存在與%d匹配的數!\n",e1);

    printf("請輸入在第幾個元素之前插入[1,%d]:",L.length+1);
    scanf("%d",&j);
    while(j<0 || j>L.length+1)
    {
        printf("超出範圍!請重新輸入!\n");
        printf("請輸入在第幾個元素之前插入[1,%d]:",L.length+1);
        scanf("%d",&j);
    }
    printf("輸入將要插入的元素:");
    scanf("%d",&ins_e);
    printf("在第%d個元素之前插入元素%d\n",j,ins_e);
    ListInsert_Sq(L,j,ins_e);
    printf("插入元素後,L表爲:");
    ListTraverse_Sq(L,print1);

    printf("請輸入要刪除第幾個元素?m = ");
    scanf("%d",&m);
    while(m<1 || m>L.length)
    {
        printf("超出範圍,請重新輸入:\n");
        printf("請輸入要刪除第幾個元素?m = ");
        scanf("%d",&m);
    }
    printf("刪除第%d個元素\n",m);
    if(ListDelete_Sq(L,m,del_e))
    {
        printf("刪除元素爲:%d\n",del_e);
        printf("刪除元素成功!\n");
    }

    printf("刪除元素之後,L表爲:");
    ListTraverse_Sq(L,print1);

    printf("清空前,L表信息爲:L.length = %d, L.listsize = %d, L.elem = %p\n",L.length,L.listsize,L.elem);
    Clear_Sq(L);
    printf("順序表L已經被清空!\nL.length = %d, L.listsize = %d, L.elem = %p\n",L.length,L.listsize,L.elem);
    Destroy_Sq(L);
    printf("順序表L已經被銷燬!\nL.length = %d, L.listsize = %d, L.elem = %p\n",L.length,L.listsize,L.elem);
    return 0;
}


//函數實現
void InitSqlist_Sq(Sqlist &L)
{
    L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(!L.elem)
        exit(OVERFLOW);
    L.length = 0;
    L.listsize = LIST_INIT_SIZE;
    return;
}

void Destroy_Sq(Sqlist &L)
{
    free(L.elem);
    L.elem = NULL;
    L.length = 0;
    L.listsize =0;
}

void Clear_Sq(Sqlist &L)
{
    L.length = 0;//不是int L.length = 0,直接令L.length = 0即可
}

Status ListEmpty_Sq(Sqlist L)
{
    if(L.length == 0)
        return OK;//注意:在程序中,返回用OK-ERROR組合和TRUE-FALSE組合都可以,根據語境進行判斷
    else
        return ERROR;
}

int ListLength_Sq(Sqlist L)
{
    return L.length;
}

Status GetElem_Sq(Sqlist L,int i,ElemType &e)
{
    if(i<1||i>L.length)
        return ERROR;
    e = *(L.elem + i - 1);//等價於 e = L.elem[i-1];
    return OK;
}

int Locate_Sq(Sqlist L,ElemType e,Status (* compare)(ElemType,ElemType))//compare()函數
{
    int i = 1;
    ElemType *p = L.elem;
    while( i<=L.length && !compare(*(p++),e))//重要:在這一行,*(p++) = *p++;
       i++;
    if(i<=L.length)
        return i;
    else
        return 0;
}

Status PriorElem_Sq(Sqlist L,ElemType cur_e,ElemType &pre_e)
{
    int i = 2;
    ElemType *p = L.elem + 1;
    while(i<=L.length && *p != cur_e)//注意這兒是while循環,不是if判斷語句
    {
        p++;
        i++;
    }
    if(i>L.length)
        return ERROR;
    else
        {
            pre_e = *(--p);//等價於pre_e = * --p;
            return OK;
        }
}

Status NextElem_Sq(Sqlist L,ElemType cur_e,ElemType &next_e)
{
    int i = 1;
    ElemType *p = L.elem;
    while(i<L.length && *p != cur_e)//尋找後繼元素,i的範圍需要小於表長,最大隻能到達倒數倒數第二個,因此不能寫 i<=L.length
    {                               //注意這兒是while循環,不是if判斷語句
        p++;
        i++;
    }
    if(i==L.length)//i = L.length的時候就結束了上邊的if-else循環,此時i = L.length
        return ERROR;
    else
    {
        next_e = *(++p);//等價於next_e = * ++p;
        return OK;
    }
}

Status ListInsert_Sq(Sqlist &L,int i,ElemType e)
{
    ElemType *newbase,*p,*q;
    if(i<1 || i>L.length+1)//這條語句說明也可以在表尾插入一個元素
        return ERROR;
    if(L.listsize == L.length)
    {
        newbase = (ElemType *)realloc(L.elem,(L.listsize+LIST_INCREMENT)*sizeof(ElemType));
        if(!newbase)//!newbase 等價於 NULL == newbase
            return ERROR;
        L.elem = newbase;
        L.listsize += LIST_INCREMENT;
    }
    p = L.elem + i - 1;//把第i個元素的地址存到p中
    for(q=L.elem+L.length-1; q>=p; q--)
        *(q+1) = *q;
    *p = e;
    ++L.length;
    return OK;
}

Status ListDelete_Sq(Sqlist &L,int i,ElemType &e)
{
    ElemType *p;
    if(i<1 || i>L.length)
        return ERROR;
    e = *(L.elem + i - 1);
    for(p = L.elem + i - 1; p <= L.elem + L.length - 1; p++)
        *p = *(p+1);
    L.length--;
    return OK;
}

Status ListTraverse_Sq(Sqlist L,void(* visit)(ElemType &e))
{
    ElemType *p = L.elem;
    int i;
    for(i = 1; i <= L.length; i++)
        visit(*p++);
    printf("\n");
    return OK;
}

源碼:http://download.csdn.net/detail/u013383042/9623543
原創:http://blog.csdn.net/u013383042/article/details/52453320

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章