数据结构(1)顺序表的实现

Sqlist.h

#ifndef _SQLIST_H_
#define _SQLIST_H_

#define LIST_INIT_SIZE 1
#define LISTINCREAMENT 1

//#define ElemType int

typedef struct
{
    char name[20];
    int age;
}ElemType;

/************************************************************************/   
/* 存储结构的定义                                                       */   
/************************************************************************/
typedef struct  
{
    ElemType *elem; /*基址的指针*/
    int length;    /*表的长度,表中元素的个数*/
    int size;    /*表的容量*/
}Sqlist;

/************************************************************************/
/* 表的基本操作                                                         */
/************************************************************************/
void InitList(Sqlist *L);/*初始化表*/
void DestroyList(Sqlist *L);/*销毁表,释放存储空间*/
void ClearList(Sqlist *L);/*将表置空*/

int IsEmpty(Sqlist *L);/*判断表是否为空,空则返回1,否则返回0 */
int Length(Sqlist *L);/*返回表的长度*/

ElemType *GetElem(Sqlist *L, int i);  /*返回表中第i个元素*/
int LocateElem(Sqlist *L, ElemType e);/*判断e是否为表中的元素,是则返回元素在表中的位置,否则返回-1*/

/*用pre_e获取元素e的前驱,返回值i为前驱在表中位置*/
/*如果e不在表中,返回-1 */
/*如果e为表中的第一个元素,返回-2*/
int PriorElem(Sqlist *L, ElemType e, ElemType *pre_e);
/*用next_e获取e的后继,返回值i为后继在表中的位置*/
/*如果e不是表中元素,返回-1*/
/*如果e为表中的最后一个元素,返回-2*/
int NextElem(Sqlist *L, ElemType e, ElemType *next_e);

/*在位置i处插入元素e,成功则返回表的长度,否则返回0*/
int Insert(Sqlist *L, ElemType e, int i);
/*删除表中的元素e,成功返回1,否则返回0*/
int Delete(Sqlist *L, int n,  ElemType *e);
/*遍历*/
void traverse(Sqlist *L);

#endif

 

Sqlist.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Sqlist.h"

/*初始化表*/
void InitList(Sqlist *L)
{
    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
    if (!L->elem)
    {
        printf("动态内存分配失败\n");
        exit(0);
    }

    L->length = 0;
    L->size = LIST_INIT_SIZE;
}

/*销毁表,释放存储空间*/
void DestroyList(Sqlist *L)
{
    if (L->elem)
        free(L->elem);
}

/*将表置空*/
void ClearList(Sqlist *L)
{
    if (L->elem)
        L->length = 0;
}

/*判断表是否为空,空则返回1,否则返回0 */
int IsEmpty(Sqlist *L)
{
    if (L->elem)
    {
        if (L->length > 0)
            return 0;
        else
            return 1;
    }else
        return -1;
}
/*返回表的长度*/
int Length(Sqlist *L)
{
    if (L->elem)
        return L->length;
    else 
        return -1;
}

/*返回表中第i个元素*/
ElemType * GetElem(Sqlist *L, int i)
{
    if (i<1 || i> L->length)
    {
        printf("此节点不存在,请检查是否正确!!!\n");
        return NULL;
    }

    return &(L->elem[i-1]);
}

/*判断e是否为表中的元素,是则返回元素在表中的位置,否则返回-1*/
int LocateElem(Sqlist *L, ElemType e)
{
    int i;
    for (i = 0; i < L->length; i++)        
    {
        //如果使用e.name == L->elem[i].name 经过测试失败(e.name="chen",同样L->elem[i].name= "chen")
        //从首地址开始逐个遍历字符比较是可以的,也就是strcmp,string.h
        if (strcmp(L->elem[i].name,e.name) == 0)  
            return i+1;
    }
    return -1;
}

/*用pre_e获取元素e的前驱,返回值i为前驱在表中位置*/
/*如果e不在表中,返回-1 */
/*如果e为表中的第一个元素,返回-2*/
int PriorElem(Sqlist *L, ElemType e, ElemType *pre_e)
{
    int local;
    local = LocateElem(L, e);
    if (local == -1)//表中不存在该元素
        return -1;
    if (local == 1)//表中的第一个元素
        return -2;

    pre_e = &(L->elem[local-1]);
    //*pre_e = L->elem[local-1] //会出错
    return (local-1);
}

int NextElem(Sqlist *L, ElemType e, ElemType *next_e)
{
    int local;
    local = LocateElem(L, e);
    if (local == -1)//表中不存在该元素
        return -1;
    
    *next_e = L->elem[local+1];
    return (local+1);
}

/*
在位置i处插入元素e,成功则返回表的长度,否则返回0
*/
int Insert(Sqlist *L, ElemType e, int i)
{
    ElemType * temp;
    int cursor;

    if (i < 1 || i > L->length + 1)
    {
        printf("\n插入位置出错啦(温馨提示n个元素,有n+1个插入位置)\n");
        return 0;
    }
    
    /*应该在此添加插入位置是否合法的判断条件*/
    if (L->length >= L->size)
    {
        /*这个很耗内存,不建议使用realloc*/
        temp = (ElemType *)realloc(L->elem, (L->size + LISTINCREAMENT)*sizeof(ElemType));
        if (!temp)
        {
            printf("动态内存分配失败overflow!!!\n");
            return 0;
        }
        L->elem = temp;
        L->size += LISTINCREAMENT;
    }

    /*
    debug error:Damage before normal block
    编译器报这样的错,几乎可以肯定是在程序中,数组访问越界,
    这面这个肯定最后一个元素是空数据,或者是垃圾数据
    DAMAGE:After normal block(#****)  
    */
    for (cursor = L->length-1; cursor >= i-1; cursor --)
        L->elem[cursor + 1] = L->elem [cursor];
    
    L->elem[i-1] = e;
    L->length++;

    return 1;
}

/*
在位置n处插入元素,并将删除元素保存在e当中
*/
int Delete(Sqlist *L, int n, ElemType *e)
{
    int i;

    if (n < 1 || n > L->length)
    {
        printf("删除位置不合法!!!\n");
        return -1;
    }
    
    e = &(L->elem[n-1]);

    for (i = n-1; i < L->length; i++)
        L->elem[i] = L->elem[i + 1];

    L->length --;
    return 1;
}

void traverse(Sqlist *L)
{
    int i = 0;
    if (!L->elem || L->length ==0)
        return;
    for (; i< L->length; i ++)
    {
        printf("\n顺序表中第%d个元素分别为:(%s,%d)", i, L->elem[i].name,L->elem[i].age);
    }
    printf("\n  ");
}

 

 

main.c

 

 

#include "Sqlist.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

int main()
{
    Sqlist L;
    int i;

    ElemType e, *ptr_e;

    InitList(&L);
    
    /*测试插入元素,在头元素位置和尾元素单独测试*/
    printf("请输入要添加的节点元素:\n例如:chen 23\n");
    for (i = 1; i < 4; i++)
    {
        fflush(stdin);
        scanf("%s%d",&e.name,&e.age);
        Insert(&L,e,i);
    }
    
/*
    //测试第一个位置
    printf("\n测试第一个位置插入\n");
    fflush(stdin);
    scanf("%s%d",&e.name,&e.age);
    Insert(&L,e,1);
    traverse(&L);
    printf("%d",L.size);
    printf("  %d\n",L.length);
    
        
    //测试最后一个位置
    printf("\n测试最后一个位置插入\n");
    fflush(stdin);
    scanf("%s%d",&e.name,&e.age);
    Insert(&L,e,L.length+1);    
    traverse(&L);
    printf("%d",L.size);
    printf("  %d\n",L.length);
*/
    
    
/*
    //测试删除第一个元素
    Delete(&L,1, &e);
    traverse(&L);
    printf("%d",L.size);
    printf("  %d\n",L.length);
    printf("\n您所删除的元素是:(%s,%d)",e.name,e.age);

    //测试删除最后一个个元素
    Delete(&L,L.length, &e);
    traverse(&L);
    printf("%d",L.size);
    printf("  %d\n",L.length);
    printf("\n您所删除的元素是:(%s,%d)",e.name,e.age);

    printf("\n");
*/

/*
    //测试取出指定位置上的元素;
    for (i = 1; i < 4; i ++)
    {
        e = *GetElem(&L,i);
        printf("\n您所找的元素是:(%s,%d)",e.name,e.age);
    }
*/
/*
    //测试定位元素
    printf("请输入要定位的元素:例如(name age)\n");
    scanf("%s%d",&e.name, &e.age); //如果这个地方丢了&,就会出现unhandle exception
    i = LocateElem(&L, e);
    printf("\n元素的位置是:%d", i);
    
*/

    //测试查找前一个元素
    printf("请输入要定位的元素:例如(name age)\n");
    scanf("%s%d",&e.name, &e.age);
    i = PriorElem(&L, e, ptr_e);
    printf("\n元素的位置是:%d", i);
    

    
    DestroyList(&L);    
    printf("\n");
    return 0;
}

 

 

 

 

posted @ 2013-09-24 12:40  CJin  阅读(424)  评论(0编辑  收藏  举报