C语言数据结构拉练----顺序表,链表

数据结构 = 结构定义 + 结构操作

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值