看数据结构写代码(19) 数组的实现

数组是 一种 使用广泛 的数据结构,任何编程语言都有数组。其本质上 是 线性表,一维数组 是 一个线性表,多维数组是多组 线性表。 其 便利性 就在于 查找 和 赋值 方便。所以 就没必要 用 链式存储方式。

下面 给出 数组的实现代码:

// Array.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <stdarg.h>

#define ARRAY_MAX_DIM	8//数组最大维度
typedef int ElementType;

enum E_STATE
{
	E_STATE_ERROR = 0,
	E_STATE_OK = 1,
};

struct Array
{
	ElementType * base;
	int dim;// 数组 是 几维数组
	int * dimLenArray;//数组 每维 的 长度
	int * dimBaseArray;//数组 每维 的 基数
};

E_STATE arrayInit(Array * array,int dim,...){
	if (dim < 1 || dim > ARRAY_MAX_DIM)//维度错误
	{
		return E_STATE_ERROR;
	}
	array->dim = dim;
	va_list ap;
	va_start(ap,dim);
	array->dimLenArray = (int *) malloc(sizeof(int) * dim);
	if (array->dimLenArray == NULL){
		va_end(ap);
		return E_STATE_ERROR;
	}
	int totalNum = 1;
	for (int i = 0; i < dim; i++){
		int len = va_arg(ap,int);
		if (len < 1)//长度 错误
		{
			va_end(ap);
			return E_STATE_ERROR;
		}
		array->dimLenArray[i] = len;
		totalNum *= len;
	}
	array->base = (ElementType *) malloc(sizeof(ElementType) * totalNum);
	if (array->base == NULL)
	{
		free(array->dimLenArray);
		array->dimLenArray = NULL;
		va_end(ap);
		return E_STATE_ERROR;
	}
	array->dimBaseArray = (int *) malloc(sizeof(int) * dim);
	if (array->dimBaseArray == NULL)
	{
		free(array->dimLenArray);
		array->dimLenArray = NULL;
		free(array->base);
		array->base = NULL;
		va_end(ap);
		return E_STATE_ERROR;
	}
	array->dimBaseArray[dim-1] = 1;
	for (int i = dim - 2; i >= 0; i--)
	{
		array->dimBaseArray[i] = array->dimBaseArray[i+1] * array->dimLenArray[i+1];
	}
	va_end(ap);
	return E_STATE_OK;
}

void arrayDestory(Array * array){
	if (array->base)
	{
		free(array->base);
		array->base = NULL;
	}
	if (array->dimBaseArray)
	{
		free(array->dimBaseArray);
		array->dimBaseArray = NULL;
	}
	if (array->dimLenArray)
	{
		free(array->dimLenArray);
		array->dimLenArray = NULL;
	}
	array->dim = 0;
}

//数组 索引 从 0 计算.. (0行 0 列 等等)
E_STATE arraylocation(Array array,va_list ap,int * off){
	*off = 0;
	for (int i = 0; i < array.dim; i++)
	{
		int dimLen = va_arg(ap,int);
		if (dimLen < 0 || dimLen >= array.dimLenArray[i])
		{
			return E_STATE_ERROR;
		}
		*off += dimLen * array.dimBaseArray[i];
	}
	//printf("location = %d \n",*off);
	return E_STATE_OK;
}

E_STATE arrayGetValue(Array array,ElementType * data,...){
	int location = 0;
	va_list ap;
	va_start(ap,data);
	if (arraylocation(array,ap,&location) == E_STATE_ERROR)
	{
		va_end(ap);
		return E_STATE_ERROR;
	}
	*data = array.base[location];
	va_end(ap);
	return E_STATE_OK;
}

E_STATE arraySetValue(Array * array,ElementType data,...){
	int location = 0;
	va_list ap;
	va_start(ap,data);
	if (arraylocation(*array,ap,&location) == E_STATE_ERROR)
	{
		va_end(ap);
		return E_STATE_ERROR;
	}
	array->base[location] = data;
	va_end(ap);
	return E_STATE_OK;
}

int _tmain(int argc, _TCHAR* argv[])
{
	Array array;
	//
	arrayInit(&array,3,3,4,5);
	int index1 = 1,index2 = 2,index3 =0;
	for (; index3 < 5; index3++)
	{
		arraySetValue(&array,index3,index1,index2,index3);
	}
	for (index3 =0; index3 < 5; index3++)
	{
		int result = -1;
		arrayGetValue(array,&result,index1,index2,index3);
		printf("%d\n",result);
	}
	arrayDestory(&array);
	return 0;
}

时间: 2024-10-23 11:13:31

看数据结构写代码(19) 数组的实现的相关文章

看数据结构写代码(32) 赫夫曼树编码以及译码

杂谈:最近有点慵懒,不好不好.好几天都没写代码,原本准备上星期完结 树 这一章节的.现在 又耽误了.哎.要抓紧时间啊. 下面直接上代码: 可以到我的网盘下载源代码,或者 直接拷贝下面的源代码 运行 网盘地址:点击打开链接 // HuffmanTree.cpp : 定义控制台应用程序的入口点. //哈弗曼编码,译码 #include "stdafx.h" #include <stdlib.h> #include <cstring> enum E_State { E

看数据结构写代码(50)伙伴系统

伙伴系统 是一种 只 可以 分配 2的 幂次方 个 空间的 ,回收 内存 时 只 合并 "伙伴空间" 的一种 动态内存管理方式. 例如 一个 空间 大小 为 64 的 内存,伙伴 系统 为 这 64 的内存  建立 一组 双向循环 链表,分别 管理着  2的 0 次方,2的1 次方幂,2的 2 次方幂...2的6次方幂的 可用空间. 即使 我们 只想分配 一个 大小 为3的 空间,系统 却 只能 返回 一个 内存 大小 为 4(2的2次方)的 一个空间. 系统 在 初始化的 时候 ,并

看数据结构写代码(61) 哈希表

前面说的 各种查找都是 基于 "比较" 的基础 来进行 查找的.查找的 效率 要 看 比较的 次数.那么 有没有 不需要 比较,就可以 找到 想要的数据的 方法呢? 哈希表 就是 这样的 一种方法,它用  数组 作为 保存 关键字的 数据原型,通过 一个 哈希 函数f(k),来找到 关键字 存储的位置,从而 找到想要的信息. 例如 我们 想要解决 这样的一个问题: 假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字母数相对少一些.什么方法能最快的查出所有小

看数据结构写代码(44) 判断无向图是否有环路

在 看 严蔚敏的 数据结构 一书 7.5小节时,书上 说" 判断有向图是否存在环要不无向图复杂.对于无向图来说,深度优先遍历过程中遇到回边(即指向已访问过的顶点的边),则必定存在环路". 看的不明白,所以 网上 百度了一下. 有了思路:故写下算法 和思路,以便以后 温故. 思路: 1.一个n个顶点,e条边的 无向图,若 e>= n,必有环路. 2.若 e < n ,需要 深度 遍历,并把 父节点传入 参数中,如果 遇到 一个 节点 被访问过 并且 不是 父节点,那么 就有环

看数据结构写代码(35) 图的邻接矩阵表示法

杂谈:最近清明小长假,好好的放松了一下.节前 和 节后 都有点 松懈.不好,不好.贵在坚持.加油. 图的邻接矩阵表示法是用 两个数组 来表示 图的数据结构.一个是顶点数组,另一个是邻接矩阵数组.邻接矩阵 里存放着 顶点的关系. 用邻接矩阵表示图,在 看 顶点之间 是否有边,或者 求顶点的度等操作时比较简单.但空间浪费巨大,在插入,删除 顶点 和边 操作时 需要 移动大量数据,造成不便.所以在插入删除比较多,节点数比较多的时候 不宜 使用这种结构. 下面上代码: 源代码网盘地址:点击打开链接 //

看数据结构写代码(40) 无向图的深度优先生成树与广度优先生成树

图的深度优先遍历 和 广度 优先 遍历 算法中的 每一次 最外层 循环 都 产生 一个 无向图 的 连通分量,每一个连通分量,都可以产生一个生成树,将这些生成树合在 一起 就是 一个 森林. 用 树的 孩子 兄弟 链表 表示法 来 表示 这个 森林, 就是 这一节 算法的  内容. 深度优先森林 代码 : //深度优先生成森林 void dfsTree(AMLGraph g,int i,Tree * t,bool isVisited[]){ isVisited[i] = true; bool i

看数据结构写代码(66) 败者树

计算机的 内存 是 有限的,无法 存入 庞大的数据.当 遇到 大数据需要排序时,我们 需要 将 这些 数据 分段 从 硬盘里 读到 内存中,排好序,再 写入到 硬盘中,这些段 叫做 归并段.最后将 这些 分段 合并 成 一个 最终  完整 有序的 数据. 这里 操作的 时间 =  内部 排序 时间 +  外存读写时间 + 内部归并所需时间. 其中 外存 读写时间 最耗时,外存读写时间 = 读写次数 * 读写数据的时间 ,读写 数据的时间 因 设备 性能 而 影响,我们 无法控制,我们 只能 控制

看数据结构写代码(42)最小生成树

首先给出 一些 概念问题: 1.生成树: 一个n个顶点的 连通图 的 极小连通子图. 它含有n个顶点,但只有 n-1条边,不存在回路. 2.最小生成树:一个带权的 无向连通图,求出 各边权值相加  最小的 生成树,叫做最小生成树. 所以 求最小生成树  首先 要满足: 1. 首先 是 无向图 2. 必须是 连通图(任意两个顶点可达)3.带权 简单的说 就是 必须是 连通网. 求 最小生成树,严蔚敏的 数据结构 给出了 两种 方法:普里姆算法和 克鲁斯卡尔算法. 普里姆算法: 克鲁斯卡尔算法: 克

看数据结构写代码(67) 置换 _ 选择排序(完结篇)

杂谈: 严蔚敏版<数据结构(C语言版)> 一书 终于看完了.这是 一个完结,也是 一个新的开端.<算法导论> 已到手. 置换选择排序的思想 是 将 归并段 尽量 变的 更大,而不是根据 内存 大小 限制在 固定的 大小. 这样 可以 利用赫夫曼树 来 进行 最优归并树,从而 使 外存 读写次数 最少. 下面给出 具体 代码:欢迎指出代码不足. // Replace_Selcetion.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h&q