算法导论代码 第10章 基本数据结构

10章 基本数据结构

10.1 栈和队列

10.1.1 

10.1.1.1 基于数组实现

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct stack_type *stack;
struct stack_type {
	int top;
	int num;
	void **array;
};
stack stack_create(int num)
{
	stack s = malloc(sizeof(struct stack_type));
	s->top = -1;
	s->num = num;
	s->array = malloc(sizeof(void *) * num);
	return s;
}

bool stack_is_empty(stack s)
{
	return s->top == -1;
}

bool stack_is_full(stack s)
{
	return s->top == s->num - 1;
}

void stack_push(stack s, void *x)
{
	s->array[++s->top] = x;
}

void *stack_pop(stack s)
{
	return s->array[s->top--];
}

void stack_destroy(stack s, void (*free_key) (void *))
{
	while (!stack_is_empty(s)) {
		void *p = stack_pop(s);
		free_key(p);
	}
	free(s->array);
	free(s);
}

int main()
{
	stack s = stack_create(10);
	for (int i = 0; i < 10; i++) {
		int *p = malloc(sizeof(int));
		*p = i;
		stack_push(s, p);
	}
	printf("stack is full?%s\n", stack_is_full(s) ? "true" : "false");
	while (!stack_is_empty(s)) {
		int *p = stack_pop(s);
		printf("%d ", *p);
		free(p);
	}
	printf("\n");
	stack_destroy(s, free);
	return 0;
}


10.1.1.2 基于链表实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct stack_type *stack;
struct stack_node {
	void *key;
	struct stack_node *next;
};
struct stack_type {
	struct stack_node *head;
};
void stack_node_ini(struct stack_node *n, void *key)
{
	n->key = key;
	n->next = NULL;
}

stack stack_create()
{
	stack s = malloc(sizeof(struct stack_type));
	s->head = NULL;
	return s;
}


bool stack_is_empty(stack s)
{
	return s->head == NULL;
}

void stack_push(stack s, void *x)
{
	struct stack_node *node = malloc(sizeof(struct stack_node));
	stack_node_ini(node, x);
	node->next = s->head;
	s->head = node;
}

void *stack_pop(stack s)
{
	struct stack_node *p = s->head;
	s->head = s->head->next;
	void *key = p->key;
	free(p);
	return key;
}

void stack_destroy(stack s, void (*free_key) (void *))
{
	while (!stack_is_empty(s)) {
		void *p = stack_pop(s);
		free_key(p);
	}
	free(s);
}

int main()
{
	stack s = stack_create();
	for (int i = 0; i < 10; i++) {
		int *p = malloc(sizeof(int));
		*p = i;
		stack_push(s, p);
	}
	while (!stack_is_empty(s)) {
		int *p = stack_pop(s);
		printf("%d ", *p);
		free(p);
	}
	printf("\n");
	stack_destroy(s, free);
	return 0;
}


10.1.2 队列

10.1.2.1 基于数组实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct queue_type *queue;
struct queue_type {
	int num;
	int head;
	int tail;
	void **array;
};
queue queue_create(int num)
{
	queue q = malloc(sizeof(struct queue_type));
	/*num比要存放在队列中的元素个数多一,是为了区分队列满和空的状态 */
	q->num = num + 1;
	q->head = 0;
	q->tail = 0;
	q->array = malloc(sizeof(void *) * num);
	return q;
}

bool queue_is_empty(queue q)
{
	return q->head == q->tail;
}

bool queue_is_full(queue q)
{
	return q->head == (q->tail + 1) % q->num;
}

void queue_en_queue(queue q, void *x)
{
	q->array[q->tail++] = x;
	q->tail = q->tail % q->num;
}

void *queue_de_queue(queue q)
{
	void *x = q->array[q->head++];
	q->head = q->head % q->num;
	return x;
}

void queue_destroy(queue q,void (*free_key)(void *))
{
	while (!queue_is_empty(q)) {
		void *p = queue_de_queue(q);
		free_key(p);
	}
	free(q->array);
	free(q);
}

int main()
{
	queue q = queue_create(10);
	for (int i = 0; i < 10; i++) {
		int *p = malloc(sizeof(int));
		*p = i;
		queue_en_queue(q, p);
	}
	printf("queue is full?:%s\n", queue_is_full(q) ? "true" : "false");
	while (!queue_is_empty(q)) {
		int *p = queue_de_queue(q);
		printf("%d ", *p);
		free(p);
	}
	printf("\n");
	queue_destroy(q,free);
	return 0;
}


10.1.2.2 基于链表实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct queue_type *queue;
struct queue_node {
	void *key;
	struct queue_node *next;
};

struct queue_type {
	struct queue_node *head;
	struct queue_node *tail;
};

void queue_node_ini(struct queue_node *node, void *key)
{
	node->key = key;
	node->next = NULL;
}

queue queue_create()
{
	queue q = malloc(sizeof(struct queue_type));
	q->head = NULL;
	q->tail = NULL;
	return q;
}

bool queue_is_empty(queue q)
{
	return q->head == NULL;
}

void queue_en_queue(queue q, void *x)
{
	struct queue_node *p = malloc(sizeof(struct queue_node));
	queue_node_ini(p, x);
	if (q->head == NULL) {
		q->head = p;
		q->tail = p;
	} else {
		q->tail->next = p;
		q->tail = p;
	}
}

void *queue_de_queue(queue q)
{
	void *key = q->head->key;
	struct queue_node *p = q->head;
	q->head = q->head->next;
	free(p);
	return key;
}

void queue_destroy(queue q, void (*free_key) (void *))
{
	while (!queue_is_empty(q)) {
		void *p = queue_de_queue(q);
		free_key(p);
	}
	free(q);
}

int main()
{
	queue q = queue_create();
	for (int i = 0; i < 10; i++) {
		int *p = malloc(sizeof(int));
		*p = i;
		queue_en_queue(q, p);
	}
	while (!queue_is_empty(q)) {
		int *p = queue_de_queue(q);
		printf("%d ", *p);
		free(p);
	}
	printf("\n");
	queue_destroy(q,free);
	return 0;
}


10.2 链表

10.2.1 双链表

#include <stdio.h>
#include <stdlib.h>
typedef struct list_type *list;
struct list_node {
	void *key;
	struct list_node *prev;
	struct list_node *next;
};
struct list_type {
	struct list_node *head;
};
void list_node_ini(struct list_node *p, void *key)
{
	p->key = key;
	p->prev = NULL;
	p->next = NULL;
}

list list_create()
{
	list l = malloc(sizeof(struct list_type *));
	l->head = NULL;
	return l;
}

void list_destroy(list l, void (*free_key) (void *))
{
	struct list_node *x = l->head;
	while (x != NULL) {
		struct list_node *del = x;
		x = x->next;
		free_key(del->key);
		free(del);
	}
	free(l);
}

struct list_node *list_search(list l, void *k,
			      int (*comp) (const void *, const void *))
{
	struct list_node *x = l->head;
	while (x != NULL && comp(x->key, k) != 0) {
		x = x->next;
	}
	return x;
}

void list_insert(list l, struct list_node *x)
{
	x->next = l->head;
	if (l->head != NULL) {
		l->head->prev = x;
	}
	l->head = x;
	x->prev = NULL;
}

void list_delete(list l, struct list_node *x)
{
	if (x->prev != NULL) {
		x->prev->next = x->next;
	} else {
		l->head = x->next;
	}
	if (x->next != NULL) {
		x->next->prev = x->prev;
	}
}

void list_display(list l, void (*print_key) (const void *))
{
	struct list_node *x = l->head;
	while (x != NULL) {
		print_key(x->key);
		printf(" ");
		x = x->next;
	}
	printf("\n");
}

int cmp_int(const void *p1, const void *p2)
{
	const int *pa = p1;
	const int *pb = p2;
	if (*pa < *pb)
		return -1;
	if (*pa == *pb)
		return 0;
	return 1;
}
void print_key(const void *key)
{
	const int *p = key;
	printf("%d", *p);
}

int main()
{
	list l = list_create();
	for (int i = 0; i < 10; i++) {
		struct list_node *n = malloc(sizeof(struct list_node));
		int *p = malloc(sizeof(int));
		*p = i;
		list_node_ini(n, p);
		list_insert(l, n);
	}
	list_display(l, print_key);
	int k = 0;
	struct list_node *node = list_search(l, &k, cmp_int);
	printf("查找关键字:%d的结果:%s\n", k,
	       node != NULL ? "成功" : "失败");
	printf("删除关键字:%d的结果:\n", k);
	list_delete(l, node);
	free(node->key);
	free(node);
	list_display(l, print_key);
	list_destroy(l,free);
	return 0;
}


10.2.2 带哨兵的环形双向链表

#include <stdio.h>
#include <stdlib.h>
/*带哨兵的环形双向链表*/
typedef struct list_circle_type *list;
struct list_node {
	void *key;
	struct list_node *prev;
	struct list_node *next;
};
struct list_circle_type {
	struct list_node *nil;	/*哑元结点,用来代替NULL */
};
void list_node_ini(struct list_node *p, void *key)
{
	p->key = key;
	p->prev = NULL;
	p->next = NULL;
}

list list_create()
{
	list l = malloc(sizeof(struct list_circle_type *));
	l->nil = malloc(sizeof(struct list_node));
	l->nil->prev = l->nil;
	l->nil->next = l->nil;
	return l;
}

void list_destroy(list l, void (*free_key) (void *))
{
	struct list_node *x = l->nil->next;
	while (x != l->nil) {
		struct list_node *del = x;
		x = x->next;
		free_key(del->key);
		free(del);
	}
	free(l->nil);
	free(l);
}

struct list_node *list_search(list l, void *k,
			      int (*comp) (const void *, const void *))
{
	struct list_node *x = l->nil->next;
	while (x != l->nil && comp(x->key, k) != 0) {
		x = x->next;
	}
	return x;
}

void list_insert(list l, struct list_node *x)
{
	x->next = l->nil->next;
	l->nil->next->prev = x;
	l->nil->next = x;
	x->prev = l->nil;
}

void list_delete(list l, struct list_node *x)
{
	if (x == l->nil)
		return;
	x->next->prev = x->prev;
	x->prev->next = x->next;
}

void list_display(list l, void (*print_key) (const void *))
{
	struct list_node *x = l->nil->next;
	while (x != l->nil) {
		print_key(x->key);
		printf(" ");
		x = x->next;
	}
	printf("\n");
}

int cmp_int(const void *p1, const void *p2)
{
	const int *pa = p1;
	const int *pb = p2;
	if (*pa < *pb)
		return -1;
	if (*pa == *pb)
		return 0;
	return 1;
}
void print_key(const void *key)
{
	const int *p = key;
	printf("%d", *p);
}

int main()
{
	list l = list_create();
	for (int i = 0; i < 10; i++) {
		struct list_node *n = malloc(sizeof(struct list_node));
		int *p = malloc(sizeof(int));
		*p = i;
		list_node_ini(n, p);
		list_insert(l, n);
	}
	list_display(l, print_key);
	int k = 0;
	struct list_node *node = list_search(l, &k, cmp_int);
	printf("查找关键字:%d的结果:%s\n", k,
	       node != l->nil ? "成功" : "失败");
	printf("删除关键字:%d的结果:\n", k);
	list_delete(l, node);
	free(node->key);
	free(node);
	list_display(l, print_key);
	list_destroy(l,free);
	return 0;
}


10.3 指针和对象的实现

#include <stdio.h>
#include <stdlib.h>
typedef struct list_type *list;
enum { NIL = -1 };
struct list_type {
	int num;
	int *key;
	int *next;
	int *prev;
	int free;
	int head;
};
list list_create(int num)
{
	list l = malloc(sizeof(struct list_type));
	l->num = num;
	l->key = malloc(sizeof(int) * num);
	l->prev = malloc(sizeof(int) * num);
	l->next = malloc(sizeof(int) * num);
	/*自由表是一个单链表,只用到next数组 */
	l->free = 0;
	for (int i = 0; i < num - 1; i++) {
		l->next[i] = i + 1;
	}
	l->next[num - 1] = NIL;
	l->head = NIL;
	return l;
}

void list_destroy(list l)
{
	free(l->key);
	free(l->prev);
	free(l->next);
	free(l);
}

int list_allocate_object(list l)
{
	if (l->free == NIL) {
		return NIL;
	} else {
		int x = l->free;
		l->free = l->next[x];
		return x;
	}
}

void list_free_object(list l, int x)
{
	if(x==NIL)
		return;
	l->next[x] = l->free;
	l->free = x;
}

int list_search(list l, int k)
{
	int x = l->head;
	while (x != NIL && l->key[x] != k) {
		x = l->next[x];
	}
	return x;
}

void list_insert(list l, int x)
{
	l->next[x] = l->head;
	if (l->head != NIL) {
		l->prev[l->head] = x;
	}
	l->head = x;
	l->prev[x] = NIL;
}

void list_delete(list l, int x)
{
	if(x==NIL)
		return;
	if (l->prev[x] != NIL) {
		l->next[l->prev[x]] = l->next[x];
	} else {
		l->head = l->next[x];
	}
	if (l->next[x] != NIL) {
		l->prev[l->next[x]] = l->prev[x];
	}
}

void list_display(list l)
{
	int x = l->head;
	while (x != NIL) {
		printf("%d ", l->key[x]);
		x = l->next[x];
	}
	printf("\n");
}

int main()
{
	list l = list_create(10);
	for (int i = 0; i < 10; i++) {
		int x=list_allocate_object(l);
		l->key[x]=i;
		list_insert(l, x);
	}
	list_display(l);
	int k = 0;
	int pos = list_search(l, k);
	printf("查找关键字:%d的结果:%s\n", k,
	       pos != NIL ? "成功" : "失败");
	printf("删除关键字:%d的结果:\n", k);
	list_delete(l,pos );
	list_free_object(l,pos);
	list_display(l);
	list_destroy(l);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值