动态顺序表的插入函数
我在运行动态顺序表的//在顺序表中第i个位置之前插入新的数据元素e,顺序表的长度加1
Status ListInsert(SqList *L , int i , ElemType e)
{
ElemType*q , *p;
ElemType *base;
if(i < 1 || i > L->length + 1)//i值不合法
return ERROR;
// 如果空间不够放,调用realloc()重新分配空间
if( L->length >= L->listsize)//当前存储空间已满,增加分配
{
//注意realloc函数的意思与malloc函数的区别,realloc为重新分配内存
//如果成功分配返回true,失败则是返回false
//重新将新基址分配给(*L).elem
if(!(base = (ElemType *)realloc(L->elem, sizeof(ElemType) * (L->listsize + LISTINCREMENT))))
//return ERROR;//存储分配失败
L->elem = base;
L->listsize += LISTINCREMENT;
}
q = L->elem + i -1;//q为插入位置,采用下一个语句也是可以的
//q = &(L->elem);
//插入位置及之后右移,先从最后一个位置开始
for(p = L->elem + L->length + 1; p >= q; --p)
*(p + 1) = *p;
*q = e;//插入e
L->length ++;//表长增1
return OK;
}
这个程序的原型是高一凡老师的《《数据结构》算法实现及解析》中的顺序表的源程序。但在运行的时候,
ListInsert(&L, 1, 0);出现
这是为什么啊,求帮助,开始我以为是程序错误,弄了好几天也没弄明白。
能否把完整的程序复制上来,结构体中都定义了哪些内容 雪是梅之香 发表于 2015-1-18 19:26
能否把完整的程序复制上来,结构体中都定义了哪些内容
主程序:
/*
Name:
Copyright:
Author:
Date: 22/12/14 16:03
Description:顺序表的实例
*/
#include "c1.h"
#include "shunxubiao.h"//包含顺序表的创建以及基本操作
int main(void)
{
SqList L;//定义一个顺序表
ElemType e, e0;
Status i;
int j, k;
i = InitList(&L);//初始化顺序表
//%u表示的是地址编号
//进行初始化后,顺序表的值没有改变,说明此时采用的是值调用,我们应该采用地址调用
printf("初始化顺序表L后:\n基址L.elem = %u表长L.length = %d初始分配容量L.listsize = %d\n", L.elem, L.length, L.listsize);
for(j = 1; j <= 5; j++)
ListInsert(&L, 1, j);//在表头位置一次输入,注意顺序表表头都是第一个位置,用数组理解就是第一个a
printf("在顺序表的表头依次插入1~5后。\n表中数据依次为:");
for(j = 1; j <=5; j++)
printf("%d", *(L.elem + j -1));
printf("\n");
printf("L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
//判断顺序表是否为空,并输出是否为空表,用条件表达式来表示
printf("顺序表L%s空表。 \n", ListEmpty(L) == TRUE ? "为" : "不为");
//进行清空操作
i = ClearList(&L);
printf("进行清空操作后:L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
//判断顺序表是否为空,并输出是否为空表
printf("进行清空操作后,此时顺序表L%s空表。\n", ListEmpty(L) == 1 ? "为" : "不为");
//从表尾位置输入数据
for(j = 1; j <= 10; j++)
i = ListInsert(&L, j, j);
printf("在顺序表的表尾依次插入1~10后。\n表中数据依次为:");
for(j = 1; j <= 10; j++)
printf("%d", *(L.elem + j -1));
printf("\n");
printf("L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
printf("\n");
//以上运行编译没有问题
//在第1个位置插入0
ListInsert(&L, 2, 0);
printf("在顺序表的插入0后。\n表中数据依次为:");
for(j = 1; j <= ListLength(L); j++)//ListLength(L)为元素个数
printf("%d", *(L.elem + j -1));
printf("\nL.elem = %u(有可能改变)L.length = %d(改变)L.listsize = %d(改变)\n", L.elem, L.length, L.listsize);
GetElem(L, 5 , &e);
printf("第5个元素的值为:%d\n",e);
DestroyList(&L);
printf("销毁顺序表L后:L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
system("PAUSE");
return 0;
}
c1.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>
#include <process.h>
//#include <iostream.h>
//函数结果状态
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status;//STATUS 是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean;//Boolean是布尔类型,其值是TRUE或FALSE
typedef int ElemType;
shunxubiao.h文件内容
//顺序表的基本操作
//线性表的动态分配顺序存储结构
//顺序表的创建
#define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量
#define LISTINCREMENT 2 //线性表存储空间的分配增量
typedef struct
{
ElemType *elem;//存储空间基址
int length;//当前长度
int listsize;//当前分配的存储容量(以sozeof(ElemType)为单位)
}SqList;
/********************************************************************************/
//顺序表的初始化
//函数要求采用地址调用,才能改变主函数中的值,动态分配内存
Status InitList(SqList *L)
{
//构造一个空的顺序线性表
(*L).elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if(!(*L).elem)
exit(0);//存储分配失败
(*L).length = 0; //空表长度为0
(*L).listsize = LIST_INIT_SIZE;//初始存储容量
return OK;
}
/********************************************************************************/
//顺序表重置为空表,即为清空
//前提条件为顺序表已经存在
Status ClearList(SqList *L)
{
(*L).length = 0;
return OK;
}
/********************************************************************************/
//若L为空表,则返回TRUE,否则返回FALSE
//前提条件顺序表已经存在
Status ListEmpty(SqList L)
{
if(L.length == 0)
return TRUE;
else
return FALSE;
}
/********************************************************************************/
//返回L中数据元素个数,即为顺序表长度
//前提条件顺序表已经存在
int ListLength(SqList L)
{
return L.length;
}
/********************************************************************************/
//用e返回顺序表中第i个数据元素的值
//初始条件顺序表已经存在,且i值有效。
Status GetElem(SqList L, int i, ElemType *e)
{
if(L.length == 0 || i < 1 || i > L.length)
return ERROR;
//没有将地址返回到主函数中????,而有时候又可以
*e = *(L.elem+ i -1 ); //给e重新赋地址值
return OK;
}
/********************************************************************************/
//顺序表的销毁
//注意前提条件是顺序表已经存在
Status DestroyList(SqList *L)
{
free(L->elem); //释放内存
L->elem = NULL;
L->length = 0;
L->listsize = 0;
return OK;
}
/********************************************************************************/
//在顺序表中第i个位置之前插入新的数据元素e,顺序表的长度加1
Status ListInsert(SqList *L , int i , ElemType e)
{
ElemType*q , *p;
ElemType *newbase;
if(i < 1 || i > L->length + 1)//i值不合法
exit(0);
// 如果空间不够放,调用realloc()重新分配空间
if( L->length >= L->listsize)//当前存储空间已满,增加分配
{
//注意realloc函数的意思与malloc函数的区别,realloc为重新分配内存
//如果成功分配返回true,失败则是返回false
//重新将新基址分配给(*L).elem
newbase = (ElemType *)realloc(L->elem, sizeof(ElemType) * (L->listsize + LISTINCREMENT));
if(!newbase)
exit(0);//存储分配失败
L->elem = newbase; //确定新基址
printf("781");
L->listsize += LISTINCREMENT;//增加存储容量
//L->listsize = L->listsize + LISTINCREMENT
}
q = L->elem + i -1;//q为插入位置,采用下一个语句也是可以的
//q = &(L->elem);
//插入位置及之后右移,先从最后一个位置开始
for(p = L->elem + L->length + 1; p >= q; --p)
*(p + 1) = *p;
*q = e;//插入e
L->length ++;//表长增1
return OK;
}
/********************************************************************************/
/********************************************************************************/
//在顺序表中第i个位置之前删除新的数据元素e,顺序表的长度减1 又重新分析了以便还是有问题,望解答! #include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <math.h>
#include <process.h>
//#include <iostream.h>
//函数结果状态
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status;//STATUS 是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean;//Boolean是布尔类型,其值是TRUE或FALSE
typedef int ElemType;
//顺序表的基本操作
//线性表的动态分配顺序存储结构
//顺序表的创建
//线性表存储空间的初始分配量
#define LIST_INIT_SIZE 10
//线性表存储空间的分配增量
#define LISTINCREMENT 2
typedef struct
{
ElemType *elem;//存储空间基址
int length;//当前长度
int listsize;//当前分配的存储容量(以sozeof(ElemType)为单位)
}SqList;
/********************************************************************************/
//顺序表的初始化
//函数要求采用地址调用,才能改变主函数中的值,动态分配内存
Status InitList(SqList *L)
{
//构造一个空的顺序线性表
(*L).elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if(!(*L).elem)
exit(0);//存储分配失败
(*L).length = 0; //空表长度为0
(*L).listsize = LIST_INIT_SIZE;//初始存储容量
return OK;
}
/********************************************************************************/
//顺序表重置为空表,即为清空
//前提条件为顺序表已经存在
Status ClearList(SqList *L)
{
(*L).length = 0;
return OK;
}
/********************************************************************************/
//若L为空表,则返回TRUE,否则返回FALSE
//前提条件顺序表已经存在
Status ListEmpty(SqList L)
{
if(L.length == 0)
return TRUE;
else
return FALSE;
}
/********************************************************************************/
//返回L中数据元素个数,即为顺序表长度
//前提条件顺序表已经存在
int ListLength(SqList L)
{
return L.length;
}
/********************************************************************************/
//用e返回顺序表中第i个数据元素的值
//初始条件顺序表已经存在,且i值有效。
Status GetElem(SqList L, int i, ElemType *e)
{
if(L.length == 0 || i < 1 || i > L.length)
return ERROR;
//没有将地址返回到主函数中????,而有时候又可以
*e = *(L.elem+ i -1 ); //给e重新赋地址值
return OK;
}
/********************************************************************************/
//顺序表的销毁
//注意前提条件是顺序表已经存在
Status DestroyList(SqList *L)
{
free(L->elem); //释放内存
free(L);
//L->elem = NULL;
//L->length = 0;
//L->listsize = 0;
return OK;
}
/********************************************************************************/
//在顺序表中第i个位置之前插入新的数据元素e,顺序表的长度加1
Status ListInsert(SqList *L , int i , ElemType e)
{
ElemType*q , *p;
ElemType *newbase;
if(i < 1 || i > L->length + 1)//i值不合法
exit(0);
// 如果空间不够放,调用realloc()重新分配空间
if( L->length == L->listsize)//当前存储空间已满,增加分配
{
//注意realloc函数的意思与malloc函数的区别,realloc为重新分配内存
//如果成功分配返回true,失败则是返回false
//重新将新基址分配给(*L).elem
newbase = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(ElemType));
if(!newbase)
{
printf("内存分配错误");
exit(0);//存储分配失败
}
//调试结果,执行完上一个语句之后,开始出现问题,分配内存出现错误
L->elem = newbase; //确定新基址
L->listsize += LISTINCREMENT;//增加存储容量
//L->listsize = L->listsize + LISTINCREMENT
}
q = L->elem + i -1;//q为插入位置,采用下一个语句也是可以的
//q = &(L->elem);
//插入位置及之后右移,先从最后一个位置开始
for(p = L->elem + L->length + 1; p >= q; --p)
*(p + 1) = *p;
*q = e;//插入e
L->length ++;//表长增1
return OK;
}
/********************************************************************************/
/********************************************************************************/
//在顺序表中第i个位置之前删除新的数据元素e,顺序表的长度减1
/*
Name:
Copyright:
Author:
Date: 22/12/14 16:03
Description:顺序表的实例
*/
int main(void)
{
SqList L;//定义一个顺序表
ElemType e, e0;
Status i;
int j, k;
i = InitList(&L);//初始化顺序表
//%u表示的是地址编号
//进行初始化后,顺序表的值没有改变,说明此时采用的是值调用,我们应该采用地址调用
printf("初始化顺序表L后:\n基址L.elem = %u表长L.length = %d初始分配容量L.listsize = %d\n", L.elem, L.length, L.listsize);
for(j = 1; j <= 5; j++)
ListInsert(&L, 1, j);//在表头位置一次输入,注意顺序表表头都是第一个位置,用数组理解就是第一个a
printf("在顺序表的表头依次插入1~5后。\n表中数据依次为:");
for(j = 1; j <=5; j++)
printf("%d", *(L.elem + j -1));
printf("\n");
printf("L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
//判断顺序表是否为空,并输出是否为空表,用条件表达式来表示
printf("顺序表L%s空表。 \n", ListEmpty(L) == TRUE ? "为" : "不为");
//进行清空操作
i = ClearList(&L);
printf("进行清空操作后:L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
//判断顺序表是否为空,并输出是否为空表
printf("进行清空操作后,此时顺序表L%s空表。\n", ListEmpty(L) == 1 ? "为" : "不为");
//从表尾位置输入数据
for(j = 1; j <= 10; j++)
i = ListInsert(&L, j, j);
printf("在顺序表的表尾依次插入1~10后。\n表中数据依次为:");
for(j = 1; j <= 10; j++)
printf("%d", *(L.elem + j -1));
printf("\n");
printf("L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
printf("\n");
/*********************************************************************************/
//以上运行编译没有问题,在下面的程序编译之后出现对话框,说明出现一个问题,程序停止,
//经过综合分析之后,可能是插入函数出现问题
//在第1个位置插入0
ListInsert(&L, 1, 0);//这个函数出现问题
printf("在顺序表的插入0后。\n表中数据依次为:");
for(j = 1; j <= ListLength(L); j++)//ListLength(L)为元素个数
printf("%d", *(L.elem + j -1));
printf("\nL.elem = %u(有可能改变)L.length = %d(改变)L.listsize = %d(改变)\n", L.elem, L.length, L.listsize);
GetElem(L, 5 , &e);
printf("第5个元素的值为:%d\n",e);
DestroyList(&L);//这个函数也出现问题
printf("销毁顺序表L后:L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
system("PAUSE");
return 0;
}
楼主没有跟踪一下是哪个函数出了错么~~设置几个断点,试试跑到哪个函数哪个位置出了错~~ 设置了,就是插入函数出错,运行realloc函数后,显示没有分配成功,同时销毁函数也有问题,但不知道错哪了,这两个函数都和书上、网上一样。
x072816 发表于 2015-5-9 22:52
设置了,就是插入函数出错,运行realloc函数后,显示没有分配成功,同时销毁函数也有问题,但不知道错哪了 ...
好吧,我翻了下严蔚敏老师的《数据结构(C语言版)》,也没看出代码有什么问题,希望有大神来帮你解决吧,说话楼主下次回复别人的时候要点别人回复你的那楼下面的一个回复键,不然没有提醒,人家不知道你回复了~~
加油吧亲,数据结构还是相当有用的~~ lightninng 发表于 2015-5-10 00:19
好吧,我翻了下严蔚敏老师的《数据结构(C语言版)》,也没看出代码有什么问题,希望有大神来帮你解决吧 ...
谢谢,我再自己研究研究吧 雪是梅之香 发表于 2015-1-18 19:26
能否把完整的程序复制上来,结构体中都定义了哪些内容
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <math.h>
#include <process.h>
//#include <iostream.h>
//函数结果状态
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status;//STATUS 是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean;//Boolean是布尔类型,其值是TRUE或FALSE
typedef int ElemType;
//顺序表的基本操作
//线性表的动态分配顺序存储结构
//顺序表的创建
//线性表存储空间的初始分配量
#define LIST_INIT_SIZE 10
//线性表存储空间的分配增量
#define LISTINCREMENT 2
typedef struct
{
ElemType *elem;//存储空间基址
int length;//当前长度
int listsize;//当前分配的存储容量(以sozeof(ElemType)为单位)
}SqList;
/********************************************************************************/
//顺序表的初始化
//函数要求采用地址调用,才能改变主函数中的值,动态分配内存
Status InitList(SqList *L)
{
//构造一个空的顺序线性表
(*L).elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if(!(*L).elem)
exit(0);//存储分配失败
(*L).length = 0; //空表长度为0
(*L).listsize = LIST_INIT_SIZE;//初始存储容量
return OK;
}
/********************************************************************************/
//顺序表重置为空表,即为清空
//前提条件为顺序表已经存在
Status ClearList(SqList *L)
{
(*L).length = 0;
return OK;
}
/********************************************************************************/
//若L为空表,则返回TRUE,否则返回FALSE
//前提条件顺序表已经存在
Status ListEmpty(SqList L)
{
if(L.length == 0)
return TRUE;
else
return FALSE;
}
/********************************************************************************/
//返回L中数据元素个数,即为顺序表长度
//前提条件顺序表已经存在
int ListLength(SqList L)
{
return L.length;
}
/********************************************************************************/
//用e返回顺序表中第i个数据元素的值
//初始条件顺序表已经存在,且i值有效。
Status GetElem(SqList L, int i, ElemType *e)
{
if(L.length == 0 || i < 1 || i > L.length)
return ERROR;
//没有将地址返回到主函数中????,而有时候又可以
*e = *(L.elem+ i -1 ); //给e重新赋地址值
return OK;
}
/********************************************************************************/
//顺序表的销毁
//注意前提条件是顺序表已经存在
Status DestroyList(SqList *L)
{
free(L->elem); //释放内存
free(L);
//L->elem = NULL;
//L->length = 0;
//L->listsize = 0;
return OK;
}
/********************************************************************************/
//在顺序表中第i个位置之前插入新的数据元素e,顺序表的长度加1
Status ListInsert(SqList *L , int i , ElemType e)
{
ElemType*q , *p;
ElemType *newbase;
if(i < 1 || i > L->length + 1)//i值不合法
exit(0);
// 如果空间不够放,调用realloc()重新分配空间
if( L->length == L->listsize)//当前存储空间已满,增加分配
{
//注意realloc函数的意思与malloc函数的区别,realloc为重新分配内存
//如果成功分配返回true,失败则是返回false
//重新将新基址分配给(*L).elem
newbase = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(ElemType));
if(!newbase)
{
printf("内存分配错误");
exit(0);//存储分配失败
}
//调试结果,执行完上一个语句之后,开始出现问题,分配内存出现错误
L->elem = newbase; //确定新基址
L->listsize += LISTINCREMENT;//增加存储容量
//L->listsize = L->listsize + LISTINCREMENT
}
q = L->elem + i -1;//q为插入位置,采用下一个语句也是可以的
//q = &(L->elem);
//插入位置及之后右移,先从最后一个位置开始
for(p = L->elem + L->length + 1; p >= q; --p)
*(p + 1) = *p;
*q = e;//插入e
L->length ++;//表长增1
return OK;
}
/********************************************************************************/
/********************************************************************************/
//在顺序表中第i个位置之前删除新的数据元素e,顺序表的长度减1
/*
Name:
Copyright:
Author:
Date: 22/12/14 16:03
Description:顺序表的实例
*/
int main(void)
{
SqList L;//定义一个顺序表
ElemType e, e0;
Status i;
int j, k;
i = InitList(&L);//初始化顺序表
//%u表示的是地址编号
//进行初始化后,顺序表的值没有改变,说明此时采用的是值调用,我们应该采用地址调用
printf("初始化顺序表L后:\n基址L.elem = %u表长L.length = %d初始分配容量L.listsize = %d\n", L.elem, L.length, L.listsize);
for(j = 1; j <= 5; j++)
ListInsert(&L, 1, j);//在表头位置一次输入,注意顺序表表头都是第一个位置,用数组理解就是第一个a
printf("在顺序表的表头依次插入1~5后。\n表中数据依次为:");
for(j = 1; j <=5; j++)
printf("%d", *(L.elem + j -1));
printf("\n");
printf("L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
//判断顺序表是否为空,并输出是否为空表,用条件表达式来表示
printf("顺序表L%s空表。 \n", ListEmpty(L) == TRUE ? "为" : "不为");
//进行清空操作
i = ClearList(&L);
printf("进行清空操作后:L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
//判断顺序表是否为空,并输出是否为空表
printf("进行清空操作后,此时顺序表L%s空表。\n", ListEmpty(L) == 1 ? "为" : "不为");
//从表尾位置输入数据
for(j = 1; j <= 10; j++)
i = ListInsert(&L, j, j);
printf("在顺序表的表尾依次插入1~10后。\n表中数据依次为:");
for(j = 1; j <= 10; j++)
printf("%d", *(L.elem + j -1));
printf("\n");
printf("L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
printf("\n");
/*********************************************************************************/
//以上运行编译没有问题,在下面的程序编译之后出现对话框,说明出现一个问题,程序停止,
//经过综合分析之后,可能是插入函数出现问题
//在第1个位置插入0
ListInsert(&L, 1, 0);//这个函数出现问题
printf("在顺序表的插入0后。\n表中数据依次为:");
for(j = 1; j <= ListLength(L); j++)//ListLength(L)为元素个数
printf("%d", *(L.elem + j -1));
printf("\nL.elem = %u(有可能改变)L.length = %d(改变)L.listsize = %d(改变)\n", L.elem, L.length, L.listsize);
GetElem(L, 5 , &e);
printf("第5个元素的值为:%d\n",e);
DestroyList(&L);//这个函数也出现问题
printf("销毁顺序表L后:L.elem = %uL.length = %dL.listsize = %d\n", L.elem, L.length, L.listsize);
system("PAUSE");
return 0;
} lightninng 发表于 2015-5-10 00:19
好吧,我翻了下严蔚敏老师的《数据结构(C语言版)》,也没看出代码有什么问题,希望有大神来帮你解决吧 ...
你用我的程序运行有没有错误啊,我用的DEVC++软件,谢谢! 雪是梅之香 发表于 2015-1-18 19:26
能否把完整的程序复制上来,结构体中都定义了哪些内容
能否帮忙看看,谢谢、我用的是DEVC++软件。 刚学数据结构,顶一下 :ton: 支持 就是来顶 支持 就是来顶 支持 :sad
页:
[1]