1. 程式人生 > >資料結構入門——動態陣列

資料結構入門——動態陣列

    陣列的一大缺點就是長度定義後不能再改變,此程式實現了動態陣列,類似於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;
}