数据结构介绍:
- 程序 = 算法 + 数据结构
- 程序设计 = 算法 + 数据结构 + 编程范式
- 数据结构 :结构定义 + 结构操作
第一节-顺序表与链表:
顺序表:
是一种更高级的数组结构。
结构定义:
struct Vector {
int *data; //数据内容
int size; //总大小
int length; //当前的数据长度,存储数据的数量
};
结构操作:
插入操作:
1、将待插入位置及以后的数据向后移动一位,先空出待插入的位置。
2、将数据插入待插入位置。
3、修改length的值
删除操作:
1、将待删除位置元素后面的元素依次向前一位赋值,完成待删除元素的覆盖,这种操作属于思维逻辑层面的删除
2、修改length的值。
代码演示:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COLOR(a, b) "\033[" #b "m" a "\033[0m"
#define GREEN(a) COLOR(a, 32)
typedef struct Vector {
int *data;
int size, length;
} Vec;
Vec *init(int n)
{
Vec *v = (Vec *)malloc(sizeof(Vec));
v->data = (int *)malloc(sizeof(int) * n);
v->size = n;
v->length = 0;
return v;
}
int expand(Vec *v)
{
int extr_size = v->size;
int *p;
while (extr_size) {
p = (int *)realloc(v->data, sizeof(int) * (v->size + extr_size));
if (p) break;
extr_size /= 2;
}
if (extr_size ==0) return 0;
v->data = p;
v->size += extr_size;
return 1;
}
int insert(Vec *v, int val, int ind)
{
if (v == NULL) return 0;
if (ind < 0 || ind >v->length) return 0;
if (v->length == v->size) {
if (!expand(v)) return 0;
printf(GREEN("sucess to expand! the Vector size is %d") "\n", v->size);
}
for (int i = v->length; i > ind; i--) {
v->data[i] = v->data[i - 1];
}
v->data[ind] = val;
v->length += 1;
return 1;
}
int erase(Vec *v, int ind)
{
if (v == NULL) return 0;
if (ind < 0 || ind >= v->length) return 0;
for (int i = ind + 1; i < v->length; i++) {
v->data[i - 1] = v->data[i];
}
v->length -= 1;
return 1;
}
void clear(Vec *v)
{
if (v == NULL) return;
free(v->data);
free(v);
return;
}
void output(Vec *v)
{
if (v == NULL) return;
printf("Vector : [");
for (int i = 0; i < v->length; i++) {
i && printf(", ");
printf("%d", v->data[i]);
}
printf("]\n");
return;
}
int main()
{
srand(time(0));
#define max_op 20
Vec *vec = init(5);
for (int i = 0; i < max_op; i++) {
int val = rand() % 100;
int ind = rand() % (vec->length + 3) - 1;
int op = rand() % 4;
switch (op) {
case 0:
case 1:
case 2: {
printf("insert %d at %d to Vector = %d\n", val, ind, insert(vec, val, ind));
} break;
case 3: {
printf("erase a iterm at %d from Vector = %d\n", ind, erase(vec, ind));
} break;
}
output(vec);
printf("\n");
}
clear(vec);
#undef max_op
return 0;
}
动态开辟内存的方式:
malloc:动态的开辟一块空间,并返回这块空间的首地址
calloc:动态的申请内存,并完成清空内存内容的操作。
realloc: 将原本的一块空间,在原有空间上再一次开辟一块空间, 成功后返回的内存地址和原有的一样,不成功则找出可以存储两倍原有数据内存空间重新开辟,并将原有空间的内容拷贝到新空间,并free掉原来的空间。第三种是前两次操作都失败的情况下,会返回一个NULL
链表:
程序内部:链表头节点head
内存内部:链表节点
结构定义:
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
struct List {
ListNode head;
int length;
} List;
结构操作:
插入操作:
- 将新的节点的指针域指向待插入位置
- 将待插入位置前驱节点指向新的节点地址
- length++
int insert(List *l, int ind, int val) { if (l == NULL) return 0; if (ind < 0 || ind > l->length) return 0; ListNode *p = &(l->head), *node = getNewNode(val); while (ind--) p = p->next; node->next = p->next; p->next = node; l->length += 1; return 1; }`
删除操作:
- 使用临时指针变量记录待删除的节点
- 将待删除的节点的后继赋给待删除节点前驱的next指针域
- length–
int erase(List *l, int ind) { if (l == NULL) return 0; if (ind < 0 || ind >= l->length) return 0; ListNode *p = &(l->head), *q; while (ind--) p = p->next; q = p->next; p->next = q->next; free(q); l->length -= 1; return 1; }
就地转置:
转置后:
void reverse(List *l) { ListNode *p = l->head.next, *q; l->head.next = NULL; while (p) { q = p->next; p->next = l->head.next; l->head.next = p; p = q; } return; }
代码演示:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COLOR(a, b) "\033[" #b "m" a "\033[0m"
#define GREEN(a) COLOR(a, 32)
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
typedef struct List {
ListNode head;
int length;
} List;
ListNode *getNewNode(int);
List *getLinkList();
void clear_node(ListNode *);
void