数据结构入门——动态数组

数组的一大缺点就是长度定义后不能再改变,此程序实现了动态数组,类似于Java中的ArrayList的结构,有增、删、排序、遍历、扩容追加等功能。

动态数组的实现:

/*
	2013年2月16日19:18:35
	此程序将数组中的元素进行追加、删除、排序、遍历输出等操作。
	与java中的各方法相同,从而更加深入理解java中的方法。
*/

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

struct Arr
{
	int * pBase;
	int len;
	int cnt;
	//int increment; //自动增长因子,便于快速增加数组长度,提高效率。
};

//函数声明
void init_arr(struct Arr *); //创造并初始化一个动态数组
bool is_empty(struct Arr *); //判断数组是否为空
bool is_full(struct Arr *); //判断数组是否为满
bool changelen_arr(struct Arr *); //改变数组长度
bool append_arr(struct Arr *); //追加数组元素
bool insert_arr(struct Arr *); //插入数组元素
bool delete_arr(struct Arr *); //删除数组元素
int get(struct Arr *); //获取数组元素
void sort_arr(struct Arr *); //排序
void show_arr(struct Arr *); //遍历输出
void inversion_arr(struct Arr *); //倒置
int find_val_arr(struct Arr *); //寻找含有此数值的元素
bool delete_all_arr(struct Arr *); //删除含有此数值的所有元素

int main(void)
{
	struct Arr arr;	

	init_arr(&arr);
	show_arr(&arr);
	changelen_arr(&arr);
	append_arr(&arr);
	insert_arr(&arr);
	delete_arr(&arr);
	show_arr(&arr);
	inversion_arr(&arr);
	show_arr(&arr);
	sort_arr(&arr);
	printf("排序后的结果为:\n");
	show_arr(&arr);
	show_arr(&arr);

	return 0;
}

void init_arr(struct Arr * pArr)
{
	int i;
	int length;

	pArr->pBase = (int *)malloc(sizeof(int));
	if (NULL == pArr->pBase)
	{
		printf("内存分配失败!\n");
		exit(-1);
	}

	printf("请输入您需要的节点长度:");
	scanf("%d", &length);

	pArr->pBase = (int *)malloc(sizeof(int)*length);
	pArr->len = length;
	pArr->cnt = 0;

	for (i=0; i<length; ++i)
	{
		printf("请输入第%d个数据:", i+1);
		scanf("%d", &pArr->pBase[i]);
		(pArr->cnt)++;
	}

	return;
}

bool is_empty(struct Arr * pArr)
{
	if (pArr->cnt == 0)
	{
		printf("数组为空!\n");
		return true;
	}
	else
		return false;
}

bool is_full(struct Arr * pArr)
{
	if (pArr->cnt == pArr->len)
	{
		return true;
	}
	else
		return false;
}

void show_arr(struct Arr * pArr)
{
	int i;

	if( is_empty(pArr) )
	{
		printf("数组为空!\n");
		return;
	}

	printf("\n数组中的数据为:\n");

	for (i=0; i<pArr->cnt; ++i)
	{
		printf("%d  ", pArr->pBase[i]);
	}
	printf("\n");

	return;
}

bool changelen_arr(struct Arr * pArr)
{
	int len;

	printf("请输入修改后的长度:len = ");
	scanf("%d", &len);

	realloc(pArr->pBase, sizeof(int)*len);
	pArr->len = len;

	if (NULL == pArr->pBase)
	{
		printf("内存重新分配失败!\n");
		return false;
	}
	else
		return true;
}

bool append_arr(struct Arr * pArr)
{
	int val;
	if ( is_full(pArr) )
	{
		printf("数组已满!\n");
		return false;
	}
	else
	{
		printf("请输入需要追加的数据:val = ");
		scanf("%d", &val);
		pArr->pBase[pArr->cnt] = val;
		(pArr->cnt)++;
		return true;
	}
}

bool insert_arr(struct Arr * pArr)
{
	int i, t;
	int pos, val;

	if ( is_full(pArr) )
	{
		printf("数组已满,无法插入!\n");
		return false;
	}

input:
	printf("请输入需要插入的位置:pos = ");
	scanf("%d", &pos);
	printf("请输入需要插入的数据:val = ");
	scanf("%d", &val);

	if (pos < 1 || pos > pArr->cnt+1)
	{
		printf("输入插入位置有误!\n");
		goto input;
	}

	for (i=pArr->cnt-1; i<pos-1; --i)  //插入和删除元素都需要循环进行位移,效率很低。
	{
		pArr->pBase[i+1] = pArr->pBase[i];
	}
	pArr->pBase[pos-1] = val;
	(pArr->cnt)++;

	return true;
}

bool delete_arr(struct Arr * pArr)
{
	int pos;
	int i;
	int val;
	if ( is_empty(pArr) )
	{
		printf("数组为空,无法删除!");
		return false;
	}

	printf("请输入您需要删除的元素位置:");
	scanf("%d", &pos);

	val = pArr->pBase[pos-1];

	for (i=pos; i<pArr->cnt-1; ++i)  //插入和删除元素都需要循环进行位移,效率很低。
	{
		pArr->pBase[i-1] = pArr->pBase[i];
	}
	printf("删除成功,您删除的元素是:%d", val);
	return true;
}

int get(struct Arr * pArr)
{
	int pos;

	printf("请输入您需要获取的元素位置:");
	scanf("%d", &pos);

	printf("元素数据为:%d\n", pArr->pBase[pos-1]);
	return pArr->pBase[pos-1];
}

//冒泡排序法
void sort_arr(struct Arr * pArr)
{
	int i, j, t;

	for (i=0; i<pArr->cnt; ++i)
		for (j=0; j<pArr->cnt-1-i; ++j)
		{
			if (pArr->pBase[j] > pArr->pBase[j+1])
			{
				t = pArr->pBase[j];
				pArr->pBase[j] = pArr->pBase[j+1];
				pArr->pBase[j+1] = t;
			}
		}

	return;
}

void inversion_arr(struct Arr * pArr)
{
	int i, j, t;

	i = 0;
	j = pArr->cnt;

	while (i < j)
	{
		pArr->pBase[i] = pArr->pBase[j];
		++i;
		--j;
	}

	return;
}

int find_val_arr(struct Arr * pArr)
{
	int i;
	int val;
	int count = 0;

	printf("请输入需要查找的元素数值:val = ");
	scanf("%d", &val);

	for (i=0; i<pArr->cnt; ++i)
	{
		if (val == pArr->pBase[i])
		{
			printf("元素的下标为:%d", i);
			count++;
		}
	}

	printf("含有此元素数值的个数为:%d", count);

	return count;
}

bool delete_all_arr(struct Arr * pArr)
{
	int i, j;
	int val;
	int count = 0;

	if ( is_empty(pArr) )
	{
		printf("数组为空,无法删除!");
		return false;
	}

	printf("请输入需要删除的元素数值:val = ");
	scanf("%d", &val);

	for (i=0; i<pArr->cnt; ++i)
	{
		if (val = pArr->pBase[i])
		{
			for (j=i; j<pArr->cnt-1; ++j)
			{
				pArr->pBase[j-1] = pArr->pBase[j];
			}

			printf("删除成功!");
			count++;
			(pArr->cnt)--;
		}
	}

	printf("删除元素的总个数为:%d", count);

	return true;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-10 07:20:01

数据结构入门——动态数组的相关文章

(2)redis的基本数据结构是动态数组

redis的基本数据结构是动态数组 一.c语言动态数组 先看下一般的动态数组结构 struct MyData { int nLen; char data[0]; }; 这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势: 1.不需要初始化,数组名直接就是所在的偏移   2.不占任何空间,指针需要占用int长度空间,空数组不占任何空间.  这个数组不占用任何内存,意味着这样的结构节省空间: 该数组的内存地址就和他后面的元素的地址相同,意味着无需初始化,数组名就是后面元素的地

从零开始实现数据结构(一) 动态数组

从零开始实现数据结构(一) 动态数组 动态数组是所有数据结构中最简单的一种,甚至在很多的语言中,数组本身就是可以不定长的.因为在学习c++的时候,使用动态数组的各种操作都不是很方便(数据结构的学习最好还是c或c++,基础打好了其他的语言数据结构就很简单).所以开始学习如何去实现一个像STL中的vector一样的动态数组. 创建数组基类CArray 因为后面还准备写一个有序数组,所以这里使用一个CArray类,把数组的各种基本特性先创建好.后面需要写什么数组,就可以写它下面的子类,来完成特殊的功能

第二十二篇 玩转数据结构——构建动态数组

1.. 数组基础 数组就是把数据码成一排进行存放. Java中,数组的每个元素类型必须相同,可以都为int类型,string类型,甚至是自定义类型. 数组的命名要语义化,例如,如果数组用来存放学生的成绩,那么命名为scores就比较合适. 索引(index)是数组中的一个重要概念,它是我们给数组中的每个元素分配的编号,从0开始,依次递增.如果数组中存放了n个元素,第一个元素的索引是0,最后一个元素的索引是n-1. 通过索引,我们可以对数组中的元素进行快速访问,例如,我们访问索引为2的元素也就是数

nginx学习七 高级数据结构之动态数组ngx_array_t

1 ngx_array_t结构 ngx_array_t是nginx内部使用的数组结构.nginx的数组结构在存储上与大家认知的C语言内置的数组有相似性,比如实际上存储数据的区域也是一大块连续的内存.但是数组除了存储数据的内存以外还包含一些元信息来描述相关的一些信息,并且可以动态增长.下面 我们从数组的定义上来详细的了解一下.ngx_array_t的定义位于src/core/ngx_array.c|h里面. struct ngx_array_s { void *elts;//数组的首地址 ngx_

可持久化数据结构入门(数组篇)

题目描述 如题,你需要维护这样的一个长度为 N 的数组,支持如下几种操作 1.在某个历史版本上修改某一个位置上的值 2.访问某个历史版本上的某一位置的值 此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本.版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组) 输入输出样例 输入样例#1 5 10 59 46 14 87 41 0 2 1 0 1 1 14 0 1 1 57 0 1 1 88 4 2 4 0 2 5 0 2 4 4 2

算法与数据结构基础1:动态数组

恶补算法与数据结构,从很基础的开始,先看动态数组的实现. // array.h #include <iostream> #include <cstring> #include <cstdlib> using namespace std; class Array { public: // ************************************************************************** // 类的四大函数:构造函数.拷贝构

数据结构动态数组

数组具有固定的容量,我们需要在初始化时指定数组的大小.有时它会非常不方便并可能造成浪费. 因此,大多数编程语言都提供内置的动态数组,它仍然是一个随机存取的列表数据结构,但大小是可变的.例如,在 C++ 中的 vector,以及在 Java 中的 ArrayList. #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { // 1. init

数据结构学习---堆栈的动态数组实现及链表实现

堆栈 [链表实现堆栈] 优点:可以无限增添元素,只要内存足够, 缺点:内存中存储位置不连续 typedef int ElementType; //只能向头部插入元素,因为如果在尾部插入,删除时,找不到上一个节点/ //因为链表是单向的 //所以 push pop 操作在头结点进行 class Stack{ public: Stack(){ S=(Stack*)malloc(sizeof(Stack)); //建立一个不存数据的头结点,方便增删节点 S->Next=NULL; sz=0; } bo

通用型动态数组的总结

基本数据结构之-通用型动态数组 动态数组的应用主要是对于长度未知的数组,先开辟一段空间来存储数据,当空间不够时,在开辟两倍的空间来存储数据 和普通数组的区别就是,我们可以不用关心数组的长度的问题,唯一需要关注的就是数据的类型是自定义数据类型还是基本数据类型,但是不论是基本数据类型还是自定义的数据类型,都需要自定义两个函数,这两个函数时遍历(打印)函数和比较函数,因为,在传递的是地址,没法再里面判断是什么类型,只能交给使用者去定义它的想关的函数, 先说基本的结构: 为了适应更多的数据类型,我们存储