【数据结构】郝斌数据结构——笔记02
首先C没有布尔类型,没办法只好自己定义一个
// 没有boolean类型,使用枚举定义 typedef enum { FALSE = 0, //逻辑假 TRUE = 1 //逻辑真 } boolean;
创建一个数组的结构体:
这个结构体定义了数组的指针,长度,有效长度,和步长
struct Array { int * pointer; // 首个元素的地址 int length; // 数组的最大个数 int counter; // 当前数组的有效个数(计数器) };
一些需要的头文件:
#include <stdio.h> #include <malloc.h> #include <stdlib.h>
对数组的一些操作:
void init(); // 初始化操作 int getElement(); // 获取元素 boolean append(); // 追加元素操作 boolean insert(); // 插入元素操作 boolean delete(); // 删除元素操作 boolean isEmpty(); // 判断是否为空 boolean isFull(); // 判断是否为满 void sort(); // 排序操作 void inversion(); // 倒置操作 void display(); // 输出展示
初始化数组:
/** * 对数组进行初始化,初始化要求设定数组的长度 * @param array * @param size */ void init(struct Array* array, int length) { // malloc函数:在内存中寻找一块参数要求大小的区域,如果成功返回该区域的首个地址 array -> pointer = (int *)malloc(sizeof (int) * length); // 如果我们要求的大小超过内存可分配的大小,则该函数返回NULL,内存分配失败 if (NULL == array -> pointer) { printf("动态内存分配失败!!!\n"); exit(-1); } array -> length = length; array -> counter = 0; // 计数器为0 return; }
判断数组为空:
/** * 判断该数组是否为空(不是为NULL!!!) * @param array * @return */ boolean isEmpty(struct Array * array) { if (0 == array -> counter) { return TRUE; } return FALSE; }
判断数组是否已满:
/** * 判断该数组是否存满 * @param array * @return */ boolean isFull(struct Array * array) { if (array -> counter == array -> length) { return TRUE; } return FALSE; }
输出数组:
/** * 展示数组 * @param array */ void display(struct Array* array) { // 如果数组是空的就不再进行程序操作 if (isEmpty(array) ) { printf("数组没有存储任何元素!!!"); } else { printf("["); for (int i = 0; i < array -> counter ; ++i) { if (i == array -> counter - 1) { printf("%d]\n", (array -> pointer)[i]); break; } printf("%d,", (array -> pointer)[i]); } } return; }
向后添加元素:
/** * 在数组中向后添加元素 * @param array * @param element * @return */ boolean append(struct Array* array, int element) { if (isFull(array)) { return FALSE; } // 我理解的是先做拨动,再放入元素,当然起始的指针开辟了并没有存值,设计的思路并没有提供直接操作的可能,所以还是先赋值 (array -> pointer)[array -> counter] = element; ++ (array -> counter); return TRUE; }
在指定位置上插入:
/** * 在指定位置插入元素 * @param array 数组变量 * @param index 指的是在数组的索引位置,该参数不能超过数组的有效范围 * @param element 要插入的元素 * @return */ boolean insert(struct Array* array, int index, int element) { // 首先判断index值是否合法 if ((index < 0) || ((array -> length) + 1 < index)) { printf("非法的索引参数!!!"); return FALSE; } // 索引合法,看数组满没满 if (isFull(array)) { printf("数组已满,无法装下更多的元素!!!"); return FALSE; } for (int i = ((array -> counter) - 1); i >= index - 1; --i) { (array -> pointer)[i + 1] = (array -> pointer)[i]; } (array -> pointer)[index - 1] = element; ++(array -> counter); return TRUE; }
这里很奇怪的操作就是为什么要减一,实际上不需要,就按照从0开始起始即可
/** * 在指定位置插入元素 * @param array 数组变量 * @param index 指的是在数组的索引位置,该参数不能超过数组的有效范围 * @param element 要插入的元素 * @return */ boolean insert(struct Array* array, int index, int element) { // 首先判断index值是否合法 if ((index < 0) || ((array -> length) + 1 < index)) { printf("非法的索引参数!!!"); return FALSE; } // 索引合法,看数组满没满 if (isFull(array)) { printf("数组已满,无法装下更多的元素!!!"); return FALSE; } for (int i = ((array -> counter) - 1); i >= index; --i) { (array -> pointer)[i + 1] = (array -> pointer)[i]; } (array -> pointer)[index] = element; ++(array -> counter); return TRUE; }
获取指定位置的元素:
/** * 获取指定位置上的元素 * @param array 数组 * @param index 索引值 * @return */ int getElement(struct Array* array, int index) { if (index > array -> counter || 0 > index) { printf("非法的索引值!!!"); return -1; } return array -> pointer [index]; }
删除元素:
/** * 删除指定索引的元素,并由pointerForSave存值 * @param array 数组 * @param index 索引值 * @param pointerForSave 存储指针 * @return 表示是否成功删除 */ boolean delete(struct Array* array, int index, int * pointerForSave) { if (index > array -> counter || 0 > index) { printf("非法的索引值!!!"); return FALSE; } if (isEmpty(array)) { return FALSE; } // 利用指针将删除的元素存储起来 *pointerForSave = array -> pointer[index]; for (int i = index; i < array -> counter; ++i) { array -> pointer[i - 1] = array -> pointer[i]; } -- array -> counter; return TRUE; }
反转数组:
/** * 反转数组的元素 * @param array */ void inversion (struct Array * array) { int head = 0; int tail = array -> counter - 1; int temp; while (head < tail) { temp = array -> pointer[head]; array -> pointer[head] = array -> pointer[tail]; array -> pointer[tail] = temp; ++ head; -- tail; } return; }
排序数组:
/** * 排序数组 * @param array */ void sort (struct Array * array) { int temp; for (int i = 0; i < array -> counter; ++i) { for (int j = i + 1; j < array -> counter; ++j) { if (array -> pointer[i] > array -> pointer[j]) { temp = array -> pointer[i]; array -> pointer[i] = array -> pointer[j]; array -> pointer[j] = temp; } } } return; }
完整代码:
#include <stdio.h> #include <malloc.h> #include <stdlib.h> // 没有boolean类型,使用枚举定义 typedef enum{ FALSE = 0, //逻辑假 TRUE = 1 //逻辑真 } boolean; // 定义一个 Array 结构体(一个自定义的数据类型) // 结构体不能加减乘除,但是可以进行赋值 struct Array { int * pointer; // 首个元素的地址 int length; // 数组的最大个数 int counter; // 当前数组的有效个数(计数器) }; void init(struct Array* array, int size); // 初始化操作 int getElement(struct Array* array, int index); // 获取元素 boolean append(struct Array* array, int element); // 追加元素操作 boolean insert(struct Array* array, int index, int element); // 插入元素操作 boolean delete(struct Array* array, int index, int * pointerForSave); // 删除元素操作 boolean isEmpty(struct Array* array); // 判断是否为空 boolean isFull(); // 判断是否为满 void sort(); // 排序操作 void inversion(); // 倒置操作 void display(struct Array* array); // 输出展示 int main() { // 定义一个Array数据类型的变量 struct Array array; init(&array, 10); append(&array,3); append(&array,9); append(&array,1); append(&array,4); display(&array); insert(&array, 0,33); display(&array); // printf("get %d", getElement(&array, 4)); inversion(&array); display(&array); sort(&array); display(&array); return 0; } /** * 对数组进行初始化,初始化要求设定数组的长度 * @param array * @param size */ void init(struct Array* array, int length) { // malloc函数:在内存中寻找一块参数要求大小的区域,如果成功返回该区域的首个地址 array -> pointer = (int *)malloc(sizeof (int) * length); // 如果我们要求的大小超过内存可分配的大小,则该函数返回NULL,内存分配失败 if (NULL == array -> pointer) { printf("动态内存分配失败!!!\n"); exit(-1); } array -> length = length; array -> counter = 0; // 计数器为0 return; } /** * 判断该数组是否为空(不是为NULL!!!) * @param array * @return */ boolean isEmpty(struct Array * array) { if (0 == array -> counter) { return TRUE; } return FALSE; } /** * 判断该数组是否存满 * @param array * @return */ boolean isFull(struct Array * array) { if (array -> counter == array -> length) { return TRUE; } return FALSE; } /** * 展示数组 * @param array */ void display(struct Array* array) { // 如果数组是空的就不再进行程序操作 if (isEmpty(array) ) { printf("数组没有存储任何元素!!!"); } else { printf("["); for (int i = 0; i < array -> counter ; ++i) { if (i == array -> counter - 1) { printf("%d]\n", (array -> pointer)[i]); break; } printf("%d,", (array -> pointer)[i]); } } return; } /** * 在数组中向后添加元素 * @param array * @param element * @return */ boolean append(struct Array* array, int element) { if (isFull(array)) { return FALSE; } // 我理解的是先做拨动,再放入元素,当然起始的指针开辟了并没有存值,设计的思路并没有提供直接操作的可能,所以还是先赋值 (array -> pointer)[array -> counter] = element; ++ (array -> counter); return TRUE; } /** * 在指定位置插入元素 * @param array 数组变量 * @param index 指的是在数组的索引位置,该参数不能超过数组的有效范围 * @param element 要插入的元素 * @return */ boolean insert(struct Array* array, int index, int element) { // 首先判断index值是否合法 if ((index < 0) || ((array -> length) + 1 < index)) { printf("非法的索引参数!!!"); return FALSE; } // 索引合法,看数组满没满 if (isFull(array)) { printf("数组已满,无法装下更多的元素!!!"); return FALSE; } for (int i = ((array -> counter) - 1); i >= index; --i) { (array -> pointer)[i + 1] = (array -> pointer)[i]; } (array -> pointer)[index] = element; ++(array -> counter); return TRUE; } /** * 获取指定位置上的元素 * @param array 数组 * @param index 索引值 * @return */ int getElement(struct Array* array, int index) { if (index > array -> counter || 0 > index) { printf("非法的索引值!!!"); return -1; } return array -> pointer [index]; } /** * 删除指定索引的元素,并由pointerForSave存值 * @param array 数组 * @param index 索引值 * @param pointerForSave 存储指针 * @return 表示是否成功删除 */ boolean delete(struct Array* array, int index, int * pointerForSave) { if (index > array -> counter || 0 > index) { printf("非法的索引值!!!"); return FALSE; } if (isEmpty(array)) { return FALSE; } // 利用指针将删除的元素存储起来 *pointerForSave = array -> pointer[index]; for (int i = index; i < array -> counter; ++i) { array -> pointer[i - 1] = array -> pointer[i]; } -- array -> counter; return TRUE; } /** * 反转数组的元素 * @param array */ void inversion (struct Array * array) { int head = 0; int tail = array -> counter - 1; int temp; while (head < tail) { temp = array -> pointer[head]; array -> pointer[head] = array -> pointer[tail]; array -> pointer[tail] = temp; ++ head; -- tail; } return; } /** * 排序数组 * @param array */ void sort (struct Array * array) { int temp; for (int i = 0; i < array -> counter; ++i) { for (int j = i + 1; j < array -> counter; ++j) { if (array -> pointer[i] > array -> pointer[j]) { temp = array -> pointer[i]; array -> pointer[i] = array -> pointer[j]; array -> pointer[j] = temp; } } } return; }