数据结构 = 结构定义 + 结构操作
1 顺序表
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 标注扩容操作的颜色宏-----"\033[32m打印值\033[0m"
#define COLOR(a, b) "\033[" #b "m" a "\033[0m"
#define GREEN(a) COLOR(a, 32)
1.1 结构定义
(1)数组指针, (2)容量, (3)长度
typedef struct Vector {
int *data;
int size, length;
} Vec;
1.2 结构操作
初始化与清空
// 返回值应指向当前数组的首地址
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;
}
void clear(Vec *v) {
if (v == NULL) return;
free(v->data);
free(v);
return;
}
扩容
使用
realloc
进行重扩建: 原址扩容 或 新值扩容, 且不一定开辟成功(返回NULL
且丢失原数据)
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 >> 1;
}
if (extr_size == 0) return 0;
printf(GREEN("expand sucess "));
v->data = p;
v->size += extr_size;
return 1;
}
插入/删除/显示
int insert(Vec *v, int val, int id) {
if (id < 0 || ind > v->length) return 0;
if (v->length == v->size) {
if (!expand(v)) {
return 0;
}
};
for (int i = v->length; i > id; --i) {
v->data[i] = data[i-1];
}
v->data[id] = val;
v->length += 1;
return 1;
}
int erase(Vec *v, int id) {
if (id < 0 || id > v->length) return 0;
if (v.length == 0) return 0;
for (int i = id; i < v->length; ++i) {
v->data[i] = v[i+1];
}
v->length -= 1;
return 1;
}
void output(Vec* v) {
if (v->length == 0) return;
printf("Vector : {");
for (int i = 0; i < v->length; ++i) {
i && printf(",");
printf("%d", v->data[i]);
}
printf("}\n");
return;
}
1.3 例程
int main() {
srand(time(0));
#define max_op 20
Vec *v = init(max_op);
for (int i = 0; i < max_op; ++i) {
int val = rand() % 100;
//int id = rand() %(v->length); //[0, v->length - 1]
// int id = rand() %(v->length + 3); //[0, v->length + 2]
int id = rand() %(v->length + 3) - 1; //[-1, v->length + 1]
int op = rand() % 4;
switch(op) {
case 0 :
case 1 :
case 2 : {
printf("insert %d at %d : %s\n",
val, id, insert(v, val, id) ? "Success" : "Fail");
} break;
case 3 : {
printf("erase at %d : %s\n",
id, erase(v, id) ? "Success" : "Fail");
} break;
}
output(v);
}
clear(v);
# undef max_op
return 0;
}
2 链表
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
2.1 结构定义
2.1.1 内部结构(存储在内存内部)
typedef struct ListNode {
int data;
struct ListNode *next; // 重命名此时尚未生效,不能替换
} ListNode;
2.1.2 外部结构(暴露在程序外部)
typedef struct List {
ListNode head; // 虚拟头结点(以便零插入)
int length;
} List;
2.2 结构操作
初始化/清除
ListNode* getNode(int val) {
ListNode* p = (ListNode *)malloc(sizeof(ListNode));
p->data = val;
p->next = NULL;
return p;
}
List* getList() {
List *l = (List*)malloc(sizeof(List));
l->head.next = NULL;
l->length = 0;
return l;
}
void clearNode(ListNode* node) {
if (!node) return;
free(node);
return;
}
void clear(List* l) {
if (!l) return;
ListNode *p = l->head.next, q;
while (p) {
q = p->next;
clearNode(p);
p = q;
}
free(l);
return;
}
插入/删除/显示
int insert(List* l, int id, int val) {
if (!l) return 0;
if (id < 0 || id > l->length) return 0;
ListNode* p = &(l->head), *node = getNode(val);
while (id--) p = p->next;
node->next = p->next;
p->next = node;
l->length += 1;
return 1;
}
int erase(List* l, int id) {
if(!l) return 0;
if(id < 0 || id > l->length) return 0;
ListNode* p = &(l->head), *q;
while (id--) p = p->next;
q = p->next;
p->next = q->next;
clearNode(q);
l->length -= 1;
return 1;
}
void output(List* l) {
if (!l) return;
printf("List(%d) = ", l->length);
for (ListNode* p = l->head.next; p; p = p->next) {
printf("%d->", p->data);
}
printf("NULL\n");
return;
}
2.3 相关算法
原地翻转
void reverse(List* l) {
if (!l) return;
ListNode* pre = l->head.next;
if (!pre) return;
ListNode* post = pre->next;
pre->next = NULL;
while (post) {
l.head->next = pre;
pre = post;
post = pre->next;
pre->next = l->head.next;
}
l->head.next = pre;
return;
}
头插入翻转
int searchId(List* l, int id) {
if (id < 0 || id > l->length) return -1;
ListNode* p = l->head.next;
for (int i = 0; i < id; ++i) {
p = p->next;
}
return p->data;
}
List* reverseHI(List* l) {
if (!l) return l;
if (!l->head.next) return l;
List* lr = getList();
for (int i = 0;i < l->length; ++i) {
insert(lr, 0, searchId(l, i));
// ListNode* node = getNode(searchId(l, i));
// node->next = lr->head.next;
// lr->head.next = node;
}
return lr;
}
2.4 例程
int main() {
srand(time(0));
#define max_op 20
List* l = getList();
for (int i = 0; i < max_op; ++i) {
int val = rand() % 100;
int id = rand() % (l->length + 3) - 1;
int op = rand() % 4;
switch(op) {
case 0:
case 1:
case 2: {
printf("insert %d at %d : %d\n",
val, id, insert(l, id, val) ? "Success" : "Fail");
} break;
case 3: {
printf("erase at %d : %d\n",
id, erase(l, id) ? "Success" : "Fail");
} break;
}
output(l);
}
printf("AtoReverse:\n");
reverse(l);
output(l);
printf("HeadInsertReverse:\n");
List* lr = reverseHI(l);
output(lr);
clear(lr);
clear(l);
#undef max_op
return 0;
}