第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;
}