設計自己的C語言版ArrayList

/*
時間:2012/06/24
目的:設計自己的ArrayList
*/
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h> //支持realloc函數
//# include <alloc.h>  //某些編譯器用realloc函數用此庫文件

struct Array//定義了一個數組類型
{
 int * pArr;//數組名
 int len;//數組的長度
 int cnt;//有效元素的個數
 double increment;//增長因子(爲大於0小於1) 當數組滿了的時候,新數組長度 = 當前長度 * (1+增長因子);
};

bool init(struct Array * arr, int len);
bool isEmpty(struct Array * arr);
bool isFull(struct Array * arr);
void showElements(struct Array * arr);
void showAllElements(struct Array * arr);
bool appendElement(struct Array * arr, int val);
bool insertElement(struct Array * arr, int index, int val);
bool deleteElement(struct Array * arr, int index, int * val);
int get(struct Array * arr, int index);
void sort(struct Array * arr);
void inverse(struct Array * arr);
void increment(struct Array * arr);

int main(void)
{
 struct Array arr;
 int len = 5;
 init(&arr, len);
 appendElement(&arr, 1);
 appendElement(&arr, 3);
 appendElement(&arr, 4);
 bool isOk = insertElement(&arr, 1, 2);
 printf("isOk = %d\n", isOk);
 insertElement(&arr, 4, 5);

 insertElement(&arr, 5, 6);
 showElements(&arr);
 //showAllElements(&arr);

 insertElement(&arr, 6, 7);
 appendElement(&arr, 8);
 appendElement(&arr, 9);
 appendElement(&arr, 10);
 showElements(&arr);

 int val;//被刪除的元素
 deleteElement(&arr, 3, &val);
 showElements(&arr);
 printf("被刪除的元素是:%d\n", val);

 inverse(&arr);
 showElements(&arr);

 sort(&arr);
 showElements(&arr);

 int num = get(&arr, 3);
 printf("取出的數是:%d\n",num);

 return 0;
}

bool init(struct Array * arr, int len)//初始化數組
{
 if (len < 1)//處理不合法的數組長度
 {
  printf("數組的長度必須大於0\n");
  exit(-1);//結束程序
 }

 arr->pArr = (int *)malloc(sizeof(int) * len);

 if (NULL == arr->pArr)//內存分配失敗   【注】 NULL 大寫
 {
  printf("sorry,內存分配失敗0\n");
  exit(-1);//結束程序
 }

 arr->len = len;
 arr->cnt = 0;
 arr->increment = 0.5;//每次數組滿了的時候,增長原來空間的一半的空間

 return true;
}

bool isEmpty(struct Array * arr)
{
 if (0 == arr->cnt)
  return true;
 else
  return false;
}

bool isFull(struct Array * arr)
{
 if (arr->len == arr->cnt)
  return true;
 else
  return false;
}

void showElements(struct Array * arr)
{
 if ( isEmpty(arr) )
 {
  printf("數組爲空!\n");
  return;//退出函數
 }

 for (int i=0; i<arr->cnt; i++)//只輸出有效的元素
 {
  if (i!=0 && i%5==0)//每行輸出五個元素
   printf("\n");
  printf("%d ", arr->pArr[i]);
 }
 printf("\n");
}

void showAllElements(struct Array * arr)
{
 if ( isEmpty(arr) )
 {
  printf("數組爲空!\n");
  return;//退出函數
 }

 for (int i=0; i<arr->len; i++)//輸出所有的元素
 {
  if (i!=0 && i%5==0)//每行輸出五個元素
   printf("\n");
  printf("%d ", arr->pArr[i]);
 }
 printf("\n");
}

bool appendElement(struct Array * arr, int val)//在數組末尾增加一個元素
{
 if ( isFull(arr) )
 {
  printf("數組已滿了,開始自動擴容。\n");
  increment(arr);
 }
 
 arr->pArr[arr->cnt] = val;//在數組末尾增加一個元素val
 arr->cnt++;//數組實際個數加1

 return true;
}

bool insertElement(struct Array * arr, int index, int val)//在數組下標爲index處插入一個元素
{
 if (index<0 || index>arr->cnt)//處理不合法的數組長度
 {
  printf("插入元素的位置只能從0到%d\n", arr->cnt);
  return false;
 }

 if ( isFull(arr) )
 {
  printf("數組已滿了,開始自動擴容。\n");
  increment(arr);
 }
 
 for (int i=arr->cnt; i>index; i--)//從index下標開始的元素各自向後移一位。
  arr->pArr[i] = arr->pArr[i-1];

 arr->pArr[index] = val;//在數組下標爲index處插入一個元素val
 arr->cnt++;//數組實際個數加1

 return true;
}

bool deleteElement(struct Array * arr, int index, int * val)//刪除數組中下標爲index的元素
{
 if (index<0 || index>=arr->cnt)//處理不合法的數組長度
 {
  printf("刪除元素的位置只能從0到%d\n", arr->cnt - 1);
  return false;
 }

 *val = arr->pArr[index];//把被刪除的數發送給主調函數中的val變量。
 
 for (int i=index; i < (arr->cnt - 1); i++)//從index下標開始的元素各自向後移一位。
  arr->pArr[i] = arr->pArr[i+1];

 free( &(arr->pArr[arr->cnt-1]) );//釋放數組最後一個元素的內存

 arr->cnt--;//數組實際個數減1
 arr->len--;//數組實際長度減1

 return true; 
}

int get(struct Array * arr, int index)//獲得數組下標爲index的元素
{
 if (index<0 || index>=arr->len)//處理不合法的數組長度
 {
  printf("獲取元素的位置只能從0到%d\n", arr->len - 1);
  exit(-1);//結束程序
 }

 return arr->pArr[index];
}

void inverse(struct Array * arr)//把有效的元素倒置
{
 int i = arr->cnt-1;
 int j = 0;
 int tmp;

 while (i > j)
 {
  tmp = arr->pArr[i];
  arr->pArr[i] = arr->pArr[j];
  arr->pArr[j] = tmp;
  i--;
  j++;
 }
}

void increment(struct Array * arr)
{
 int newLen = arr->len * (1 + arr->increment);
 printf("newLen = %d\n", newLen);
 printf("原數組的地址是%p\n", arr->pArr);
 arr->pArr = (int *)realloc(arr->pArr, newLen*sizeof(int) );//此函數會自動保留之前數組中的元素。【注】千萬別忘了*sizeof(int),因爲newLen是新數組的長度,而不是所佔的內存大小
 printf("新的原數組的地址是%p\n", arr->pArr);

 if (NULL == arr->pArr)
 {
  printf("重新分配內存失敗,程序已終止。");
  exit(-1);
 }
 
 arr->len = newLen;//千萬別忘了修改原數組的長度。
}

void sort(struct Array * arr)
{
 bool flag;
 int i, j;
 int tmp;

 for (i=0; i<arr->len; ++i)
 {
  flag = true;//提高效率
  for (j=0; j < (arr->len - i - 1); ++j)
  {
   if ( arr->pArr[j] > arr->pArr[j+1])//按成績升序
   {
    flag = false;//有元素進行了大小交換。
    tmp = arr->pArr[j];
    arr->pArr[j] = arr->pArr[j+1];
    arr->pArr[j+1] = tmp;
   }
  }
  if (flag)//所有元素本次都沒有進行大小交換,說明排序已經完成。因此跳出最外層的循環。
   break;
 }
}
/*
程序運行的結果:
===========================================================================
isOk = 1
數組已滿了,開始自動擴容。
newLen = 7
原數組的地址是00790F08
新的原數組的地址是00790F08
1 2 3 4 5
6
數組已滿了,開始自動擴容。
newLen = 10
原數組的地址是00790F08
新的原數組的地址是00790F08
1 2 3 4 5
6 7 8 9 10
1 2 3 5 6
7 8 9 10
被刪除的元素是:4
10 9 8 7 6
5 3 2 1
1 2 3 5 6
7 8 9 10
取出的數是:5
===========================================================================

總結:
---------------------------------------------------------------------------------------
struct Array//定義了一個數組類型
{
 int * pArr;//數組名
 int len;//數組的長度
 int cnt;//有效元素的個數
 double increment;//增長因子(爲大於0小於1) 當數組滿了的時候,新數組長度 = 當前長度 * (1+增長因子);
};

精華爲此結構體的定義
它體現了封裝的思想
---------------------------------------------------------------------------------------
*/

發佈了22 篇原創文章 · 獲贊 8 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章