1. 程式人生 > >資料結構---線性表(連續儲存)

資料結構---線性表(連續儲存)

ArrayList.h :結構的定義,基本函式的申明

#ifndef __ARRAYLIST_H__
#define __ARRAYLIST_H__

//一些庫函式的標頭檔案包含
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <math.h>

//自定義bool
typedef int Boolean;

//定義函式返回狀態
typedef int Status;

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0

/* 陣列擴容時,申請的記憶體大小 */
#define LIST_INCREAMENT 10

/* 線性表結構型別的定義 */
typedef struct Arr
{
	int *pBase;//陣列第一個元素的地址
	int len; //陣列最大容量
	int cnt; //當前陣列有效元素的個數
}*Arrp,Arr;

/* 線性表的初始化 ,指定線性表的長度*/
Status init(Arrp *ap);

/* 線性表空間的釋放 */
Status destroy(Arrp *ap);

/* 重置表 */
Status clear(Arrp p);

/* 判斷空 */
Boolean isEmpty(Arr p);

/* 判斷是否達到最大容量 */
Status isFull(Arr p);

/* 獲取已存元素的數量 */
int listLen(Arrp ap);

/* 線性表的插入 */
Status insertElem(Arrp p, int pos, int x);

/* 線性表元素的刪除 */
Status deleteElem(Arrp p, int pos);

/* 獲取元素 */
Status getElem(Arrp p, int pos, int *elem);

/* 根據指定的函式關係,獲取第一個滿足關係的元素索引 */
int LocateElem(Arrp p, int elem, Status (*compare)(int, int));

/* 獲取元素的前驅 */
Status PriorElem(Arr p, int pos, int *pre);

/* 獲取元素的後繼 */
Status NextElem(Arr p, int pos, int *next);

/* 根據指定的函式關係,對元素進行操作 */
void traverse(Arrp p, int pos, void (*vi)(int *));



#endif

ArrayList.c : 函式的實現

#include "ArrayList.h"

/* 線性表的初始化 ,指定線性表的長度*/
Status init(Arrp *ap)
{
    //分配一個結構單元的空間,並讓指標變數指向他
    *p = (Arrp)malloc(sizeof(Arr));
    if((*p) == NULL)
    {
        printf("動態記憶體分配失敗");
        exit(-1);
    }

    //分配單元中的base成員的空間
    (*p)->pBase = (int *)malloc(sizeof(int)*LIST_INCREAMENT);
    if((*p)->pBase == NULL)
    {
        printf("動態記憶體分配失敗");
        exit(-1);
    }

    (*p)->len = 0;
    (*p)->cnt = 0;
    
    return OK;
}

/* 線性表空間的釋放 */
Status destroy(Arrp *ap)
{
    free((*ap)->pBase);
    free((*ap));
    *ap = NULL;
    return OK;
}

/* 重置表 */
Status clear(Arrp p)
{
    p->cnt = 0;
    p->len = 0;
    free(p->pBase);
    p->pBase = (int *)malloc(sizeof(int) * LIST_INCREAMENT);
    return OK;
}

/* 判斷空 */
Boolean isEmpty(Arr p)
{
    if(p->cnt == 0)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/* 判斷是否達到最大容量 */
Status isFull(Arr p)
{
    if(p->len == p->cnt)
    {
        return TRUE;
    }
    else
    {
        return FALSE;   
    }
}

/* 獲取已存元素的數量 */
int listLen(Arrp ap)
{
    return ap->cnt;
}

/* 線性表的插入 */
Status insertElem(Arrp p, int pos, int x)
{
    int i;
    int *newBase;
    //如果空間滿了
    if(isFull(p) == TRUE)
    {
        newBase = (int *)realloc(p->pBase, (LIST_INCREAMENT + P->len)*sizeof(int));
        if(newBase == NULL)   
        {
            printf("動態記憶體分配失敗");
            exit(-1);
        }

        p->pBase = newBase;
        p->len += LIST_INCREAMENT;
    }
    
    //超過索引範圍
    if(pos < 0 || pos > p->cnt-1)
    {
        return ERROR;
    }

    for(i=p->cnt-1; i>=pos; i--)
    {
        p->pBase[i+1] = p->pBase[i];
    }

    p->pBase[pos] = x;
    p->cnt++;
    return OK;
}

/* 線性表元素的刪除 */
Status deleteElem(Arrp p, int pos)
{
    int i;
    //超過索引範圍
    if(pos < 0 || pos > p->cnt-1)
    {
        return ERROR;
    }

    for(i=pos;i<p->cnt;i++)
    {
        p->pBase[i] = p->pBase[i+1];
    }
    p->cnt--;
    return OK;
}

/* 獲取元素 */
Status getElem(Arrp p, int pos, int *elem)
{
     //超過索引範圍
    if(pos < 0 || pos > p->cnt-1)
    {
        return ERROR;
    }
    
    *elem = p->pBase[pos];
    return OK;
}

/** 
 *  根據指定的函式關係,獲取第一個滿足關係的元素索引 
 *  compare函式型別的返回值只能是0或1,滿足條件返回1,否則返回0
**/
int LocateElem(Arrp p, int elem, Status (*compare)(int, int))
{
    int i;
    int * b = p-pBase;

    for(i=0; i<p->cnt; i++)
    {
        if(compare(*b++, elem))
        {
            return i;
        }
    }
    
    return -1;
}

/* 獲取元素的前驅 */
Status PriorElem(Arr p, int pos, int *pre)
{
    //超過索引範圍,或者是第一個元素
    if(pos <= 0 || pos > p->cnt-1)
    {
        return ERROR;
    }
    
    //第一個元素沒有前驅
   // if(pos == 0)
    //{
    //    return INFEASIBLE;
   // }
    
    *pre = p->pBase[pos-1];
    return OK;
}

/* 獲取元素的後繼 */
Status NextElem(Arr p, int pos, int *next)
{
    //超過索引,或者是最後一個元素
    if(pos < 0 || pos >= p->cnt-1)
    {
        return ERROR;
    }

    *next = p->pBase[pos+1];
    return OK;
}

/* 根據指定的函式關係,對元素進行操作 */
void traverse(Arrp p, int pos, void (*vi)(int *))
{
    int i=0;
    while(i < p->cnt)
    {
        vi(p->pBase[i]);
        i++;
    }
    return;
}