常用数据结构大汇总-全部代码实现

阅读引言: 嵌入式开发的化, 重点看链表, 了解树和图肯定也是可以的我个人觉得, 个人觉得数据结构这里多画图。

目录

一、数据结构引入

1、数据结构引入

1.1数据结构解决什么问题

二、顺序表

三、链表

四、栈

1.顺序栈

2.链式栈

五、队列

1.循环队列

2.链式队列

六、栈和队列的应用-球钟问题

七、二叉树

八、图

九、哈希查找

​编辑

十、排序

1.冒泡

2.选择

3.插入

4.快速排序

5.库函数的qsort


一、数据结构引入

1、数据结构引入


1.1数据结构解决什么问题


数据结构可以将杂乱无章的数据管理起来, 提高数据的访问效率

计算机处理的对象(数据)已不再单纯是数值

其中系、办公室、……教师、学生可视为数据元素。元素之间呈现的是一种层次关系

设田径比赛项目有:A(跳高)、 B(跳远)、C(标枪)、D(铅球)、E(100m跑)、F(200m跑)。参赛选手的项目表,如下表所列:

2.数据结构的逻辑关系


                     

二、顺序表

/* squence_list.h */
#ifndef _SQUENCE_LIST_H
#define _SQUENCE_LIST_H
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
 
#define N 128
typedef int data_t;           /* 在编译的时候处理 */
typedef struct {
	data_t arr[N];             /* 顺序表的存储空间 */
	int last;                  /* 数组的最后一个元素的下标, last为-1代表数组中没有元素 */
}sq_list, *sq_link;
 
sq_link sqlist_create(void);                                    /* 创建顺序表 */
int sq_list_clear(sq_link p);                                   
int is_empty(sq_link p);
int get_length(sq_link p);
int sqlist_insert(sq_link p, data_t value, int pos);
void sqlist_show(sq_link p);
void sqlist_delete(sq_link p);
int sqlist_delete_pos(sq_link p, int pos);
int sqlist_locate(sq_link p, data_t value);
int two_sqlist_merge(sq_link p1, sq_link p2);
int delete_repeate_element(sq_link p);
 
#endif
/* squence_list.c */
#include "squence_list.h"
 
 
sq_link sqlist_create(void)
{
	sq_link p = (sq_link)malloc(sizeof(sq_list));
	if(p == NULL) {
		printf("%s malloc is failed!\n", __func__);
		return NULL;
	}
 
	memset(p, 0, sizeof(sq_list));
	p->last = -1;
 
	return p;
}
 
int sq_list_clear(sq_link p)
{
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
 
	memset(p, 0, sizeof(sq_list));
	p->last = -1;
 
	return 0;
}
 
int is_empty(sq_link p) 
{
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
	if(p->last == -1) {
		return 1;
	}
	return 0;
}
 
int get_length(sq_link p)
{
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
 
	return (p->last + 1);
	
}
 
/* 顺序表的缺点: 涉及到插入数据和删除数据的时候会有大量的数据移动 */
int sqlist_insert(sq_link p, data_t value, int pos) 
{
	int i;
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
	if(p->last >= N) {
		printf("squence list is full!\n");
		return -1;
	}
 
	/* 存储位置必须连接着 */
	if(pos < 0 || pos > p->last + 1) {
		printf("index of arrary is invalid!\n");
		return -2;
	}
 
	/* 将位于pos位置后的数据移动 */
	for(i = p->last; i >= pos; i--) {
		p->arr[i + 1] = p->arr[i];
	}
	p->arr[pos] = value;
	p->last++;
 
	return 0;
	
}
 
void sqlist_show(sq_link p)
{
	int i;
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return ;
	}
 
	if(p->last == -1) {
		printf("squence list is empty!\n");
		return ;
	}
	
	for(i = 0; i <= p->last; i++) {
		printf("%d ", p->arr[i]);
	}
	puts("");
	
}
 
 
void sqlist_delete(sq_link p)
{
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return;
	}
 
	free(p);
	p = NULL;         /* 防止野指针页虚悬空指针 */
}
 
 
int sqlist_delete_pos(sq_link p, int pos) 
{
	int i;
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
 
	if(pos < 0 || pos > p->last) {
		printf("index of delete is invalid!\n");
		return -1;
	}
 
	for(i = pos; i < p->last; i++) {
		p->arr[i] = p->arr[i + 1];
	}
 
	p->last--;
 
	return 0;
}
 
int sqlist_locate(sq_link p, data_t value)
{
	int i;
	if(p == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
 
	for(i = 0; i <= p->last; i++) {
		if(p->arr[i] == value) {
			return i;
		}
	}
 
	return -1;
}
 
 
/* 将p1和p2的并集插入到p1中 */
int two_sqlist_merge(sq_link p1, sq_link p2)
{
 
	int i = 0;
	if(p1 == NULL || p2 == NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
 
	while(i < p2->last) {
		if(sqlist_locate(p1, p2->arr[i]) == -1) {
			sqlist_insert(p1, p2->arr[i], p1->last + 1);
		}
		i++;
	}
 
	return 0;
}
 
 
/* 删除顺序表中的重复元素 */
int delete_repeate_element(sq_link p)
{
	int i = 0, j = 0;
	if(p ==NULL) {
		printf("param of %s is NULL!\n", __func__);
		return -1;
	}
 
	if(p->last == 0) {
		return -1;
	}
 
	while(i < p->last) {
		j = i + 1;
		while(j <= p->last) {
			if(p->arr[i] == p->arr[j]) {
				sqlist_delete_pos(p, j);
			} 
			j++;
		}
		i++;
	}
 
	return 0;
}

三、链表

/* link_list.h */
#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_
 
/**********************************************
 *Author: Hewei
 *Date: 2024-3-3
 *Brife: link list some operator method
 *
 *
 *arithmetic evaluate stadend
 *1.validty
 *2.time
 *3.space
 *4.read
 *
 * ********************************************/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
 
#define DEBUG(msg) \
	printf("-----%s-----%s------\n", __func__, msg);
 
typedef int data_t;
typedef struct node{
	data_t data;
	struct node *next;            /* 启用的结构体必须有一个结构体名 */
}list_node, *list_link;
 
 
 
/* link list base operator */
list_link list_create();
void list_free(list_link H);
int list_tail_insert(list_link H, data_t value);
void list_show(list_link H);
list_link list_find_pos(list_link H, int positon);
int list_positon_insert(list_link H, data_t value, int positon);
int list_delete_positon(list_link H, int positon);
int list_delete_allnode(list_link H);
int list_reverse(list_link H);
list_link list_adjoin_max(list_link H, data_t *max_value);
int list_oderly_merge(list_link H1, list_link H2);
int list_sort_ascdending(list_link H);
 
 
/*link list advance operator */
list_link list_site_reverse(list_link H);
void list_show_nohead(list_link H);
int list_has_cycle(list_link H);
size_t list_length(list_link H); 
list_link find_public_node(list_link H1, list_link H2);
list_link find_rear_knode_normal(list_link H, int rear_num);
list_link find_rear_knode_advance(list_link H, int rear_num);
list_link find_middle_node(list_link H);
int delete_repeate_element(list_link H);
 
#endif
/* link_list.c */
#include "link_list.h"
 
 
/*
 *brife: create a link_list, return the head node of linklist
 *param:none
 *
 * */
list_link list_create()
{
	list_link H = (list_link)malloc(sizeof(list_node));
	if(H == NULL) {
		DEBUG("H equal NULL\n");	
		return NULL;
	}
	
	H->data = 0;        /* 链表的头节点的数据域为0 */
	H->next = NULL;
 
	return H;
}
 
 
 
/*brife: free a linklist
 *param: address fo linklist 
 *return: none
 *
 * */
void list_free(list_link H)
{
	list_link p;
	if(H == NULL) {
		DEBUG("H equal NULL\n");	
		return ;
	}
	 
	while(H != NULL) {
		p = H;
		H = p->next;
		printf("free: %d ", p->data);
		free(p);
	}
	puts("");
}
 
 
/*brife: insert a value to link_list, from tail
 *param: list_link
 *param: value of insert
 *return: 0 succese -1 failed
 * */
int list_tail_insert(list_link H, data_t value) 
{
	if(H == NULL) {
		DEBUG("H equal NULL\n");	
		return -1;
	}
 
	list_link p = H;
	list_link tmp = (list_link)malloc(sizeof(list_node));
	if(tmp == NULL) {
		DEBUG("tmp node malloc is failed!\n");
		return -1;
	}
 
	tmp->data = value;
	tmp->next = NULL;
 
	while(p->next != NULL) {
		p = p->next;
	}
 
	p->next = tmp;
 
	return 0;
}
 
 
/*brife: foreach a linklist
 *param: address of linklist
 *return: none
 *
 * */
void list_show(list_link H)
{
	if(H == NULL) {
		DEBUG("H equal NULL\n");	
		return ;
	}
	list_link tmp = H;
 
	while(tmp->next != NULL) {
		printf("%d ", tmp->next->data);
		tmp = tmp->next;
	}
 
	puts("");
}
 
 
/*brife: return assign pos address of node 
 *
 * */
list_link list_find_pos(list_link H, int positon)
{
	list_link p;
 
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return NULL;
	}
	
	p = H;
 
	if(positon < 0) {
		DEBUG("---1---param positon is invalid!\n");
		return NULL;
	}
 
	while(positon > 0) {
		p = p->next;
		if(p == NULL) {
			DEBUG("---2---param positon is invalid!\n");
			return NULL;
		}
		positon--;
	}
	
	return p;
}
 
 
/*brife: assign positon insert
 *
 * */
int list_positon_insert(list_link H, data_t value, int positon)
{
	list_link p, q;
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return -1;
	}
 
	/* new node */
	q = (list_link)malloc(sizeof(list_node));
	if(q == NULL) {
		DEBUG("malloc failed!\n");
		return -1;
	}
	q->data = value;
	q->next = NULL;
	
	/* locate positon */
	p = H;
	while(positon - 1 > 0) {
		p = p->next;
		if(p == NULL) {
			DEBUG("param positon is invalid!\n");
			return -1;
		}
		positon--;
	}
 
	/* 先保存后节点的地址 */
	q->next = p->next;
	p->next = q;
 
	return 0;
	
}
 
 
/*brife: delete link list specify node, base positon
 *
 * */
int list_delete_positon(list_link H, int positon)
{
	list_link p, q;
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return -1;
	}	
 
	p = H;
	/*locate prior node*/
	while(positon - 1 > 0) {
		p = p->next;
		if(p == NULL) {
			DEBUG("delete positon is invalid!\n");
			return -1;
		}
		positon--;
	}
	
	q = p->next;
 
	p->next = q->next;
	q->data = 0;
	free(q);
 
	return 0;
 
}
 
 
/*brife: delete all node, but except head node 
 *
 * */
int list_delete_allnode(list_link H)
{
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return -1;
	}	
	
	list_link p = H->next, q;
	while(p != NULL) {
		q = p;
		p = p->next;
		free(q);
	}
 
	return 0;
}
 
 
/*brife: link list reverse
 *
 * */
int list_reverse(list_link H)
{
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return -1;
	}
 
	if(H->next == NULL || H->next->next == NULL) {
		DEBUG("link list only head node or a data node!\n");
		return -1;
	}
 
	list_link p = H->next->next, q;
	H->next->next = NULL;
 
	while(p != NULL) {
		q = p;
		p = p->next;
		q->next = H->next;
		H->next = q;
	}
 
	return 0;
	
}
 
 
/*brife: return address of adjoin node max value, and max_value
 *
 * */
list_link list_adjoin_max(list_link H, data_t *max)
{
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return NULL;
	}
	
	if(H->next == NULL || H->next->next == NULL) {
		DEBUG("no adjoin max value!\n");
		return NULL;
	}
 
	data_t max_value = 0;	
	list_link p, q;
	p = H->next;
	q = p->next;
	max_value = p->data + q->data;
 
	while(q != NULL) {
		if(p->data + q->data > max_value) {
			max_value = p->data + q->data;
		}
 
		p = p->next;
		q = q->next;
	}
 
	*max = max_value;
 
	return p;
}
 
 
/*brife: two oderly linklist merge
 *
 * */
int list_oderly_merge(list_link H1, list_link H2)
{                                       
	if(H1 == NULL || H2 == NULL) {
		DEBUG("param H1 or H2 is NULL!\n");	
		return -1;
	}	
 
	if(H1->next == NULL || H2->next == NULL) {
		DEBUG("data node too few!\n");
		return -1;
	} 
 
	list_link p, q, r;
	p = H1->next;
	q = H2->next;
	r = H1;
	H1->next = NULL;
	H2->next = NULL;
 
	while(p != NULL && q != NULL) {
		if(p->data > q->data) {
			r->next = q;
			q = q->next;
			r = r->next;
			r->next = NULL;
		} else {
			r->next = p;
			p = p->next;
			r = r->next;
			r->next = NULL;
		}
	}
 
	/* 一定有一个先到尾部 */
	if(p == NULL) {
		r->next = q;
	} else {
		r->next = p;
	}
	
	return 0;
}
 
 
/*
*  brife: insert sort
**/
int list_sort_ascdending(list_link H)
{
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return -1;
	}
 
	list_link p, q, r;
	p = H->next;
	H->next = NULL;
 
	while(p != NULL) {
		q = p;
		r = H;
		p = p->next;
 
		while(r->next != NULL && r->next->data < q->data)
			r = r->next;
		q->next = r->next;
		r->next = q;
	}
 
	return 0;
}
 
 
 
 
/********************************************************************************/
/**          link list some advance method                    **/
/********************************************************************************/
/*brife: on site reverse
 *return: new address of link list
 *
 * */
list_link list_site_reverse(list_link H)
{
	if(H == NULL || H->next == NULL) {
		DEBUG("param is NULL or can not reverse because node too few!\n");
		return NULL;
	}
 
	list_link p, q, r;
 
	p = H->next;
	q = p->next;
	r = q->next;
	p->next = NULL;
 
	while(r != NULL) {
		q->next = p;
		p = q;
		q = r;
		r = q->next;
	}
 
	q->next = p;
 
	return q;
}
 
 
void list_show_nohead(list_link H)
{
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return ;
	}
 
	list_link p = H;
	while(p != NULL) {
		printf("%d ", p->data);
		p = p->next;
	}
	puts("");
	
}
 
 
/*brife: judge a link list has cycle
 *return 0:have -1 no have
 *
 * */
int list_has_cycle(list_link H)
{
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return -1;
	}
 
	list_link fast = H, slow = H;
	while(fast != NULL) {
		slow = slow->next;
		if(fast->next == NULL) {
			return -1;
		}
		fast = fast->next->next;
 
		if(fast == slow) {
			return 0;
		}
	}
 
	return -1;
}
 
 
/*brife: get link list length, contain head node
 *
 * */
size_t list_length(list_link H)
{
	if(H == NULL) {
		DEBUG("param H is NULL!\n");
		return -1;
	}
 
	list_link p = H;
	unsigned int len = 0;
 
	while(p != NULL) {
		len++;
		p = p->next;
	}
 
	return len;
}
 
/*brife: find two public node of link list 
 *
 * */
list_link find_public_node(list_link H1, list_link H2)
{
	if(H1 == NULL || H2 == NULL) {
		DEBUG("param is NULL!\n");
		return NULL;
	}
 
	size_t len1, len2, len_differ;
	len1 = list_length(H1);
	len2 = list_length(H2);
 
	list_link p = H1, q = H2;
 
	if(len1 > len2) {
		len_differ = len1 - len2;
		while(p != NULL && len_differ > 0) {
			p = p->next;
			len_differ--;
		}
	} else {
		len_differ = len2 - len1;
		while(q != NULL && len_differ > 0) {
			q = q->next;
			len_differ--;
		}
	}
	
	while(p != NULL && q != NULL) {
		if(p == q) {
			return p;
		}
		p = p->next;
		q = q->next;
	}
 
	return NULL;
}
 
/*brife: find list rear K node address
 *
 * */
list_link find_rear_knode_normal(list_link H, int rear_num)
{
	if(H == NULL) {
		DEBUG("param is NULL!\n");
		return NULL;
	}
 
	size_t len = list_length(H);
	int i = 0;
	list_link p = H;
 
	for(;i < len - rear_num; i++) {
		p = p->next;	
	}
 
	return p;
}
 
 
/*brife: find list rear K node address, advance verssion
 *
 * */
list_link find_rear_knode_advance(list_link H, int rear_num)
{
	if(H == NULL) {
		DEBUG("param is NULL!\n");
		return NULL;
	}
 
	list_link p = H, q = H;
	while(rear_num > 0) {
		q = q->next;
		rear_num--;
	}
 
	while(q->next != NULL) {
		p = p->next;
		q = q->next;
	}
 
	return p;
}
 
 
/*brife: find middle node of link list 
 *
 * */
list_link find_middle_node(list_link H)
{
	if(H == NULL) {
		DEBUG("param is NULL!\n");
		return NULL;
	}
 
	if(H->next == NULL) {
		DEBUG("only head node!\n");
		return NULL;
	}
 
	list_link slow = H, fast = H;
	while(fast->next != NULL) {
		slow = slow->next;
		if(fast->next->next == NULL) {
			return slow;
		}
		fast = fast->next->next;
	}
 
	return slow;
}
 
 
 
/*brife: delete link list repeate element
 *
 * */
int delete_repeate_element(list_link H)
{
	if(H == NULL) {
		DEBUG("param is NULL!\n");
		return -1;
	}
 
	if(H->next == NULL || H->next->next == NULL) {
		DEBUG("only head node or a data node!\n");
		return -1;
	}
 
	list_link p = H->next, q;
 
	while(p != NULL) {
		while(p->next != NULL && p->data == p->next->data) {
			q = p->next;
			p->next = q->next;
			free(q);
		}
		p = p->next;
	}
 
 
	return 0;
}

四、栈

1.顺序栈

/* squence_stack.h */
#ifndef _SQUENCE_STACK
#define _SQUENCE_STACK
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define DEBUG(msg) printf("---%s---%d, ---%s---", __func__,__LINE__, msg)
 
typedef int data_t;
typedef struct {
	data_t *p_data;
	int top;
	int maxlen;
}SqStack_t;
 
SqStack_t *sqstack_create(int len);
int sqstack_free(SqStack_t *s);
int sqstack_clear(SqStack_t *s);
int sqstack_push(SqStack_t *s, data_t data);
data_t sqstack_pop(SqStack_t *s);
int sqstack_isempty(SqStack_t *s);
int sqstack_isfull(SqStack_t *s);
data_t sqstack_top_value(SqStack_t *s);
 
#endif
/* squence_stack.c */
#include "squence_stack.h"
 
SqStack_t *sqstack_create(int len)
{
	SqStack_t *p = (SqStack_t *)malloc(sizeof(SqStack_t));
	if(p == NULL) {
		DEBUG("malloc failed!\n");
		return NULL;
	}
 
	p->p_data = (data_t *)malloc(sizeof(data_t) * len);
	if(p->p_data == NULL) {
		free(p);
		DEBUG("malloc failed!\n");
		return NULL;
	}
	
	memset(p->p_data, 0, sizeof(data_t) * len);
	p->top = -1;
	p->maxlen = len;
 
	return p;
}
 
int sqstack_free(SqStack_t *s)
{
	if(s == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	s->maxlen = 0;
	s->top = -1;
	if(s->p_data != NULL)
		free(s->p_data);
	free(s);
 
	return 0;
}
 
int sqstack_clear(SqStack_t *s)
{
	if(s == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	memset(s->p_data, 0, sizeof(data_t) * s->maxlen);
	s->top = -1;
	
	return 0;
}
 
 
int sqstack_push(SqStack_t *s, data_t data)
{
	if(s == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	if(s->top < s->maxlen) {
		s->top++;
		s->p_data[s->top] = data;
	} else {
		DEBUG("top beyond maxlen\n");
		return -1;
	}
 
	return 0;
}
 
 
 
 
data_t sqstack_pop(SqStack_t *s)
{
	if(s == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	return s->p_data[s->top--];
}
 
int sqstack_isempty(SqStack_t *s)
{
	if(s == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	return (s->top == -1? 1 : 0);
}
 
 
int sqstack_isfull(SqStack_t *s)
{
	if(s == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	return (s->top == s->maxlen - 1 ? 1:0);
	
}
 
 
data_t sqstack_top_value(SqStack_t *s)
{
	if(s == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	return (s->p_data[s->top]);
}

2.链式栈

/* link_stack.h */
 
#ifndef _LINK_STACK_H
#define _LINK_STACK_H
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define DEBUG(msg) \
	printf("%s, %s", __func__, msg)
 
typedef int data_t;
typedef struct node {
	data_t data;
	struct node *next;
}node_stack, *link_stack;
 
link_stack link_stack_create();
int link_stack_free(link_stack H);
int link_stack_push(link_stack H, data_t value);
data_t link_stack_pop(link_stack H);
void link_stack_show(link_stack H);
data_t get_top_value(link_stack H);
int link_stack_isempty(link_stack H);
 
#endif
/* link_stack.c */
#include "link_stack.h"
 
/*brife: create a link stack, return heap address of link stack 
 *
 * */
link_stack link_stack_create()
{
	link_stack H = NULL;
 
	H = (link_stack)malloc(sizeof(node_stack));
	if(H == NULL) {
		DEBUG("malloc failed\n");
		return NULL;
	}
 
	H->data = 0;
	H->next = NULL;
 
	return H;
}
 
 
/*brife: release a link stack 
 *
 * */	
int link_stack_free(link_stack H)
{
	if(H == NULL) {
		DEBUG("param is NULL\n");
		return -1;
	}
 
	link_stack p = NULL;
 
	while(H != NULL) {
		p = H;
		H = H->next;
		free(p);
	}
 
	return -1;
}
 
 
/*brife: entry stack
 *
 * */
int link_stack_push(link_stack H, data_t value)
{
	if(H == NULL) {
		DEBUG("param is NULL\n");
		return -1;
	}
 
	link_stack p = (link_stack)malloc(sizeof(node_stack));
	if(p == NULL) {
		DEBUG("malloc failed\n");
		return -1;
	}
 
	p->next = NULL;
	p->data = value;
 
	p->next = H->next;
	H->next = p;
	
	return 0;
}
 
/*brife: out stack
 *
 * */
data_t link_stack_pop(link_stack H)
{
	if(H == NULL) {
		DEBUG("param is NULL\n");
		return -1;
	}
 
	data_t ret = H->next->data;
	link_stack p = H->next;
	H->next = p->next;
	free(p);
 
	return ret;
}
 
 
/*brife: foreach the link stack
 *
 * */
void link_stack_show(link_stack H)
{
	if(H == NULL) {
		DEBUG("param is NULL\n");
		return ;
	}
		
	link_stack p = H->next;
 
	while(p != NULL) {
		printf("%d ", p->data);
		p = p->next;
	}
	puts("");
 
	return ;
}
 
 
/*brife: get value of link stack top 
 *
 * */
data_t get_top_value(link_stack H)
{
	if(H == NULL) {
		DEBUG("param is NULL\n");
		return -1;
	}
 
	if(H->next == NULL) {
		return -1;
	}
 
	return H->next->data;
}
 
 
/*brife: judge link stack is empty?
 *
 * */
int link_stack_isempty(link_stack H)
{
	if(H == NULL) {
		DEBUG("param is NULL\n");
		return -1;
	}
 
	return (H->next == NULL?1:0);
}

五、队列

1.循环队列

/* squence_queue.h */
#ifndef _SQUENCE_QUEUE_H_
#define _SQUENCE_QUEUE_H_
 
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define QUEUE_SIZE 128
#define DEBUG(msg) \
	printf("--%s--, %s", __func__, msg)
 
typedef int data_t;
typedef struct {
	data_t arr[QUEUE_SIZE];
	int front, rear;
}squence_queue_t;
 
squence_queue_t *SqQueue_Create(void);
int SqQueue_Free(squence_queue_t *q);
int SqQueue_Clear(squence_queue_t *q);
int SqQueue_Entry(squence_queue_t *q, data_t value);
data_t SqQueue_Departure(squence_queue_t *q);
int SqQueue_Isempty(squence_queue_t *q);
int SqQueue_Isfull(squence_queue_t *q);
 
 
#endif
/* squence_queue.c */
#include "squence_queue.h"
 
 
/*brife: create a cycle queue
 *para: none
 *ret: heap zone addrees
 * */
squence_queue_t *SqQueue_Create(void)
{
	squence_queue_t *q = NULL;
 
	q = (squence_queue_t *)malloc(sizeof(squence_queue_t));
	if(q == NULL) {
		DEBUG("malloc failed\n");	
		return NULL;
	}
 
	memset(q->arr, 0, sizeof(data_t) * QUEUE_SIZE);
	q->front = 0;
	q->rear = 0;
 
	return q;
}
 
 
/*brife: free a cycle in heap space
 *para: cycle queue pointer
 *ret: 0 succsess  other failed
 * */
int SqQueue_Free(squence_queue_t *q)
{
	if(q == NULL) {
		DEBUG("param is invalid!\n");	
		return -1;
	}
 
	free(q);
	q = NULL;
	
	return 0;
}
 
/*brife: clear cycle queue content
 * 
 * */
int SqQueue_Clear(squence_queue_t *q)
{
	if(q == NULL) {
		DEBUG("param is invalid!\n");	
		return -1;
	}
 
	memset(q->arr, 0, sizeof(data_t) * QUEUE_SIZE);
	q->front = q->rear = 0;
 
	return 0;
}
 
/*brife: cycle queue entry operator
 *
 * */
int SqQueue_Entry(squence_queue_t *q, data_t value)
{
	if(q == NULL) {
		DEBUG("param is invalid!\n");	
		return -1;
	}
 
	if((q->rear + 1) % QUEUE_SIZE == q->front) {
		DEBUG("queue is full, entry failed!\n");	
		return -1;
	}
 
	q->arr[q->rear] = value;
	q->rear = (q->rear + 1) % QUEUE_SIZE;
 
	return 0;
}
 
 
/*brife: cycle queue departure operator
 *
 * */
data_t SqQueue_Departure(squence_queue_t *q)
{
	if(q == NULL) {
		DEBUG("param is invalid!\n");	
		return -1;
	}
 
	data_t ret;
	ret = q->arr[q->front];
	q->front = (q->front + 1) % QUEUE_SIZE;
 
	return ret;
}
 
 
/*brife: judge cycle queue is empty?
 *ret: 1---empty
 * 	   0---no empty	
 * */
int SqQueue_Isempty(squence_queue_t *q)
{
	if(q == NULL) {
		DEBUG("param is invalid!\n");	
		return -1;
	}
 
	return (q->front == q->rear ? 1 : 0);
}
 
/*brife: judge a cycle queue is full?
 *ret: 1---full
 *     0---no full
 * */
int SqQueue_Isfull(squence_queue_t *q)
{
	if(q == NULL) {
		DEBUG("param is invalid!\n");	
		return -1;
	}
 
	return ((q->rear + 1) % QUEUE_SIZE == q->front ? 1 : 0);
}

2.链式队列

/* link_queue.h */
#ifndef _LINK_QUEUE_H_
#define _LINK_QUEUE_H_
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define DEBUG(msg) \
	printf("--%s--, --%s--\n", __func__, msg);
 
typedef int data_t;
typedef struct link_queue {
	data_t data;
	struct link_queue *next;
}queue_t;
typedef struct {
	queue_t *head;
	queue_t *rear;
}linkqueue_t;
 
linkqueue_t *link_queue_create();
int link_queue_free(linkqueue_t *lq);
int link_queue_entry(linkqueue_t *lq, data_t value);
data_t link_queue_departure(linkqueue_t *lq);
int link_queue_clear(linkqueue_t *lq);
int link_queue_isempty(linkqueue_t *lq);
 
#endif
/* link_queue.c */
#include "link_queue.h"
 
 
linkqueue_t *link_queue_create()
{
	linkqueue_t *p = NULL;
 
	p = (linkqueue_t *)malloc(sizeof(linkqueue_t));
	if(p == NULL) {
		DEBUG("malloc failed\n");
		return NULL;
	}
 
	p->head = p->rear = (queue_t *)malloc(sizeof(queue_t));
	if(p->head == NULL) {
		DEBUG("malloc failed\n");
		return NULL;
	}
 
	p->head->data = 0;
	p->head->next = NULL;
 
 
	return p;
}
 
 
int link_queue_free(linkqueue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	queue_t *p = lq->head;
 
	while(lq->head != NULL) {
		p = lq->head;
		lq->head = lq->head->next;
		free(p);
	}
 
	free(lq);
	lq = NULL;
 
	return 0;
 
}
 
 
int link_queue_entry(linkqueue_t *lq, data_t value)
{
	if(lq == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	queue_t *p = (queue_t *)malloc(sizeof(queue_t));
	if(p == NULL) {
		DEBUG("new node malloc failed\n");
		return -1;
	}
 
	p->data = value;
	p->next = NULL;
 
	lq->rear->next = p;
	lq->rear = lq->rear->next;
 
	return 0;
	
}
 
data_t link_queue_departure(linkqueue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	data_t ret = 0;
	queue_t *p;
 
	ret = lq->head->next->data;
	p = lq->head;
	lq->head = lq->head->next;
 
	free(p);
 
	return ret;
}
 
 
int link_queue_clear(linkqueue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	queue_t *p;
 
	while(lq->head->next != NULL) {
		p = lq->head->next;
		lq->head = p->next;
		free(p);
		p = NULL;
	}
 
	return 0;
}
 
 
int link_queue_isempty(linkqueue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is invalid\n");
		return -1;
	}
 
	return (lq->head == lq->rear ? 1 : 0);
}

六、栈和队列的应用-球钟问题

  • 球钟问题描述

球钟是一个利用球的移动来记录时间的简单装置, 它有三个可以容纳若干个球的指示器:分钟指示器,五分钟指示器,小时指示器, 若分钟指示器中有2个球,五分钟指示器中有6个球,小时指示器中有5个球,则时间为5:32

  • 原理

每过一分钟,球钟就会从球队列的队首取出一个球放入分钟指示器,分钟指示器最多可容纳4个球。当放入第五个球时,在分钟指示器的4个球就会按照他们被放入时的相反顺序加入球队列的队尾。而第五个球就会进入五分钟指示器。按此类推,五分钟指示器最多可放11个球,小时指示器最多可放11个球

  • 需求

当小时指示器放入第12个球时,原来的11个球按照他们被放入时的相反顺序加入球队列的队尾,然后第12个球也回到队尾。这时,三个指示器均为空,回到初始状态,从而形成一个循环。因此,该球钟表示时间的范围是从0:00到11:59。

现设初始时球队列的球数为27,球钟的三个指示器初态均为空。问,要经过多久,球队列才能回复到原来的顺序?

/* squence_stack.h */
#ifndef _SQUENCE_STACK_H_
#define _SQUENCE_STACK_H_
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
typedef int data_t;
typedef struct {
	data_t *p_data;
	int maxlen;
	int top;
}squence_stack_t;
 
squence_stack_t *squence_stack_create(int maxlen);
int squence_stack_free(squence_stack_t *sq);
int stack_isempty(squence_stack_t *sq);
int stack_isfull(squence_stack_t *sq);
int squence_stack_entry(squence_stack_t *sq, data_t data);
data_t squence_stack_departure(squence_stack_t *sq);
 
 
#endif
/* squence_stack.c */
#include "squence_stack.h"
 
 
squence_stack_t *squence_stack_create(int maxlen)
{
	squence_stack_t *sq = (squence_stack_t *)malloc(sizeof(squence_stack_t));
	if(sq == NULL) {
		printf("%s, first malloc is failed\n", __func__);
		return NULL;
	}
 
	sq->p_data = (data_t *)malloc(sizeof(data_t) * maxlen);
	if(sq->p_data == NULL) {
		free(sq);
		printf("%s, second malloc failed\n", __func__);
		return NULL;
	}
 
	memset(sq->p_data, 0, sizeof(data_t) * maxlen);
	sq->top = -1;
	sq->maxlen = maxlen;
 
	return sq;
}
 
 
int squence_stack_free(squence_stack_t *sq)
{
	if(sq == NULL) {
		printf("%s, param is NULL\n", __func__);
		return -1;
	}
	
	memset(sq->p_data, 0, sizeof(data_t) * sq->maxlen);
	if(sq->p_data != NULL) {
		free(sq->p_data);
	}
	sq->maxlen = 0;
	sq->top = -1;
	free(sq);
 
	return 0;
}
 
int stack_isempty(squence_stack_t *sq)
{
	if(sq == NULL) {
		printf("%s, param is NULL\n", __func__);
		return -1;
	}
 
	return (sq->top == -1 ? 1 : 0);
}
 
int stack_isfull(squence_stack_t *sq)
{
	if(sq == NULL) {
		printf("%s, param is NULL\n", __func__);
		return -1;
	}
 
	return (sq->top == sq->maxlen - 1 ? 1 : 0);
}
 
int squence_stack_entry(squence_stack_t *sq, data_t data)
{
	if(sq == NULL) {
		printf("%s, param is NULL\n", __func__);
		return -1;
	}
 
	if(!stack_isfull(sq)) {
		sq->top++;
		sq->p_data[sq->top] = data;
	} else {
		printf("squence stack is full!\n");
		return -1;
	}
 
	return 0;
}
 
data_t squence_stack_departure(squence_stack_t *sq)
{
	if(sq == NULL) {
		printf("%s, param is NULL\n", __func__);
		return -1;
	}
 
	data_t ret;
	if(!stack_isempty(sq)) {
		ret = sq->p_data[sq->top];
		sq->top--;
	} else {
		printf("squence stack is empty\n");
		return -1;
	}
 
	return ret;
}
/* link_queue.h */
#ifndef _LINK_QUEUE_H
#define _LINK_QUEUE_H
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define DEBUG(msg) \
	printf("--%s--, %s\n",__func__,  msg)
 
typedef int data_t;
typedef struct node{
	data_t data;
	struct node *next;
}link_list;
 
typedef struct {
	link_list *front;
	link_list *rear;
}link_queue_t;
 
link_queue_t *link_queue_create();
int link_queue_free(link_queue_t *lq);
int link_queue_entry(link_queue_t *lq, data_t value);
data_t link_queue_departure(link_queue_t *lq);
int queue_empty(link_queue_t *lq);
int queue_clear(link_queue_t *lq);
 
 
#endif
/* link_queue.c */
#include "link_queue.h"
 
link_queue_t *link_queue_create()
{
	link_queue_t *lq = NULL;
	
	lq = (link_queue_t *)malloc(sizeof(link_queue_t));
	if(lq == NULL) {
		DEBUG("malloc failed");
		return NULL;
	}
 
	lq->front = lq->rear = (link_list *)malloc(sizeof(link_list));
	if(lq->front == NULL) {
		free(lq);
		DEBUG("malloc failed");
		return NULL;
	}
 
	lq->front->data = 0;
	lq->front->next = NULL;
 
	return lq;
}
 
int link_queue_free(link_queue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is NULL");
		return -1;
	}
 
	link_list *p = NULL;
	
	while(lq->front != NULL) {
		p = lq->front;
		lq->front = p->next;
		free(p);
	}
	free(lq);
 
	return 0;
}
 
int link_queue_entry(link_queue_t *lq, data_t value)
{
	if(lq == NULL) {
		DEBUG("param is NULL");
		return -1;
	}
 
	link_list *p = (link_list *)malloc(sizeof(link_list));
	if(p == NULL) {
		DEBUG("malloc failed");
		return -1;
	}
 
	p->next = NULL;
	p->data = value;
 
	lq->rear->next = p;
	lq->rear = p;
 
	return 0;
}
 
 
data_t link_queue_departure(link_queue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is NULL");
		return -1;
	}
 
	link_list *p;
	data_t ret;
 
	ret = lq->front->next->data;
	p = lq->front;
	lq->front = p->next;
 
	free(p);
 
	return ret;
}
 
 
int queue_empty(link_queue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is NULL");
		return -1;
	}
 
	return (lq->front == lq->rear ? 1 : 0);
	
}
 
int queue_clear(link_queue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is NULL");
		return -1;
	}
	
	link_list *p = NULL;
	
	while(lq->front->next != NULL) {
		p = lq->front;
		lq->front = p->next;
		free(p);
	}
 
	return 0;
}
/* test.c */
#include "squence_stack.h"
#include "link_queue.h"
 
int check(link_queue_t *lq);
 
int main(int argc, const char *argv[])
{
	link_queue_t *lq;
	squence_stack_t *s_hour, *s_five, *s_min;
	int i = 1;
	int count = 0;
	data_t value;
 
	lq = link_queue_create();
	if(lq == NULL) {
		printf("create queue failed\n");
		return -1;
	}
 
	for(;i <= 27; i++) {
		link_queue_entry(lq, i);
	}
 
	s_hour = squence_stack_create(11);
	if(s_hour == NULL) {
		printf("create hour squence stack failed\n");
		return -1;
	}
 
	s_five = squence_stack_create(11);
	if(s_hour == NULL) {
		printf("create five squence stack failed\n");
		return -1;
	}
 
	s_min = squence_stack_create(4);
	if(s_hour == NULL) {
		printf("create min squence stack failed\n");
		return -1;
	}
 
    
	while(1) {
		count++;
		if(!queue_empty(lq)) {
			value = link_queue_departure(lq);
			if(!stack_isfull(s_min)) {                   /* 分钟栈不满 */
				squence_stack_entry(s_min, value);
			} else {                                    /* 分钟栈满 */
				while(!stack_isempty(s_min)) {
					link_queue_entry(lq, squence_stack_departure(s_min));
				}
				if(!stack_isfull(s_five)) {
					squence_stack_entry(s_five, value);
				} else {
					while(!stack_isempty(s_five)) {
						link_queue_entry(lq, squence_stack_departure(s_five));
					}
					if(!stack_isfull(s_hour)) {
						squence_stack_entry(s_hour, value);
					} else {
						while(!stack_isempty(s_hour)) {
							link_queue_entry(lq, squence_stack_departure(s_hour));
						}		
 
						link_queue_entry(lq, value);
						if(check(lq) == 1) {
							break;
						}
					}
				}
			}
		}
	}
 
	printf("total: %d\n", count);
 
	puts("departure: ");
	while(!queue_empty(lq)) {
		printf("%d ", link_queue_departure(lq));
	}
	puts("");
 
 
	return 0;
}
 
int check(link_queue_t *lq)
{
	if(lq == NULL) {
		DEBUG("param is NULL");
		return -1;
	}
 
	link_list *p = lq->front->next;
	while(p->next && p) {
		if(p->data < p->next->data) {
			p = p->next;
		} else {
			return 0;
		}
	}
 
	return 1;
}

七、二叉树

/* binary_tree.h */
#ifndef _BINARY_TREE_H
#define _BINARY_TREE_H
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define DEBUG(msg) \
	printf("--%s--, %s\n", __func__, msg);
 
typedef char data_t;
typedef struct node {
	data_t data;
	struct node *lnext, *rnext;
}bitree_t;
 
 
bitree_t *binary_tree_create();
void preorder(bitree_t *r);
void inorder(bitree_t *r);
void postorder(bitree_t *r);
 
#endif
/* binary_tree.c */
#include "binary_tree.h"
 
bitree_t *binary_tree_create()
{
	char ch;
	bitree_t *root = NULL;
 
	scanf("%c", &ch);
	if(ch == '#')
		return NULL;
 
	root = (bitree_t *)malloc(sizeof(bitree_t));
	if(root == NULL) {
		DEBUG("malloc failed");	
		return NULL;
	}
 
	root->data = ch;
	root->lnext = binary_tree_create();
	root->rnext = binary_tree_create();
 
	return root;
}
 
void preorder(bitree_t *r)
{
	if(r == NULL) {
		return ;
	}
	printf("%c ", r->data);
	preorder(r->lnext);
	preorder(r->rnext);
	
}
 
void inorder(bitree_t *r)
{
	if(r == NULL) {
		return ;
	}
	inorder(r->lnext);
	printf("%c ", r->data);
	inorder(r->rnext);
	
}
 
void postorder(bitree_t *r)
{
	if(r == NULL) {
		return ;
	}
 
	postorder(r->lnext);
	postorder(r->rnext);
	printf("%c ", r->data);
	
}

八、图

# Makefile 
CC=gcc
CFLAGS= -g -Wall
SRCS=test.c graph.c link_queue.c
OBJS=$(SRCS:.c=.o)                   #variable replace     
APP=test
 
all:$(OBJS)                         #指定一个目标, 不然默认目标不会检查依赖文件的时间戳
	$(CC) $(SRCS) -o $(APP)
.PHONY:clean
clean:
	rm ./*.o $(APP)
/* graph .h */
#ifndef _GRAPH_H_
#define _GRAPH_H_
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define MAXN 128
 
typedef int element_type;
typedef struct {
	element_type vertex[MAXN];
	element_type edge[MAXN][MAXN];
	int reality_num;
}graph_t;
 
graph_t *graph_create(int n, element_type a[][n]);
int graph_release(graph_t *g);
void vertex_edge_show(graph_t *g);
void DFS(graph_t *g, int v);
void BFS(graph_t *g, int v);
 
#endif
/* graph .c */
#include "graph.h"
#include "link_queue.h"
 
/*
*brife: create graph
*/
graph_t *graph_create(int n, element_type a[][n])
{
	if(a == NULL) {
		printf("%s, param is invalid\n", __func__);
		return NULL;
	}
 
	graph_t *g = (graph_t *)malloc(sizeof(graph_release));
	if(g == NULL) {
		printf("%s, malloc failed\n", __func__);
		return NULL;
	}
 
	int i, j;
	for(i = 0; i < n; i++) {
		g->vertex[i] = i;					
		for(j = 0; j < n; j++) {
			g->edge[i][j] = a[i][j];
		}
	}
 
	g->reality_num = n;
 
	return g;
}
 
/*
*brife: release graph
*/
int graph_release(graph_t *g)
{
	if(g == NULL) {
		printf("%s, param is invalid\n", __func__);
		return -1;
	}
	
	memset(g, 0, sizeof(graph_t));
	free(g);
	
	return 0;
}
 
/*
* brife: check vertex and edge
*/
void vertex_edge_show(graph_t *g)
{
	if(g == NULL) {
		printf("%s, param is invalid\n", __func__);
		return;
	}
 
	int i, j;
 
	printf("vertex:\n");
	for(i = 0; i < g->reality_num; i++) {
		printf("%d ", g->vertex[i]);
	}
	puts("");
 
	printf("edge:\n");
	for(i = 0; i < g->reality_num; i++) {
		for(j = 0; j < g->reality_num; j++) {
			printf("%d ", g->edge[i][j]);
		}
		puts("");
	}
	puts("");
 
	return;
}
 
 
/*brife: 深度优先遍历
 *
 * */
void DFS(graph_t *g, int v)
{
	if(g == NULL) {
		printf("%s, param is NULL\n", __func__);
		return ;
	}
 
	/* 每一次递归使用的就是同一个记录数组 */
	static int visited[MAXN];                /* 数组标记的方法判断某些问题 */
	int i;
 
	printf("V%d ", v);
	visited[v] = 1;
 
	for(i = 0; i < g->reality_num; i++) {
		if(g->edge[v][i] == 1 && visited[i] == 0)
			DFS(g, i);
	}
 
	return ;
}
 
 
/*brife: graph breadth foreach
 *
 * */
void BFS(graph_t *g, int v)
{	
	if(g == NULL) {
		printf("%s, param is NULL\n", __func__);
		return ;
	}
 
	int i, visited[MAXN] = {0};
	
	linkqueue_t *lq;
	if((lq = link_queue_create()) == NULL) {
		printf("%s, link queue create failed\n", __func__);
		return;
	}
	printf("V%d ", v);
	visited[v] = 1;
	
	link_queue_entry(lq, v);
 
	while(!link_queue_isempty(lq)) {
		v = link_queue_departure(lq);
		for(i = 0; i < g->reality_num; i++) {
			if(g->edge[v][i] == 1 && visited[i] == 0) {
				printf("V%d ", g->vertex[i]);
				visited[i] = 1;
				link_queue_entry(lq, i);
			}
		}
	}
 
	return;
}

九、哈希查找


质数: 对于大于1的正自然数, 处理1和它本身别的数都无法整除它, 这个数就是质数
hash函数的确定: 
α(质量因子) = 0.7-0.8比较合适
m:存储数据的真实个数
n:存储空间的大小

α = m / n, 这样就能将n的值确定下来

给定一个数, 需要判断这个数存储再哈希表的哪一个位置, 这个时候需要引出hash函数
p:该质数一般取比存储空间小的最大质数,保证hash表的散列度好
H(key) = key % p(质数)


链式哈希和顺序哈希

以上的算法, 肯定有数据元素对应的hash的索引值是一致的, 这个叫做冲突,解决冲突的方法有两种:
1.对于顺序存储的哈希表, 再冲突的位置的基础上加上步长
2.对于链式存储的hash表, 将经过hash函数处理之后索引值一样的数据元素使用一条链表串起来, 这样查找的时候, 最多也是对这条链表查找。

#ifndef _HASH_H
#define _HASH_H
 
/****************************************************
 *
 *
 *Author:hewei
 *Date:2024-3-9
 *File:hash.h
 *Note: value = hash(key) = key % MOD;
 *
 *
 *
 *************************************************/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define N 15
#define MOD 15           
 
 
 
typedef int datatype;
typedef struct node {
	datatype key;
	int value;
	struct node *next;
}list_node, *link_list;
 
typedef struct {
	list_node data[N];
}hash_t;
 
hash_t *hash_create();
int hash_free(hash_t *h);
int hash_insert(hash_t *h, datatype value);
link_list hash_search(hash_t *h, datatype key);
 
 
 
/***********************************
 *
 *Base search, squence search and binary search, assess ASL平均查找长度
 *
 *********************************/
int squence_search(int *arr, int arr_len, int obj_value);
int binary_search(int *arr, int arr_len, int obj_value);
 
#endif
#include "hash.h"
 
 
/*brife: create a link hash table
 *
 * */
hash_t *hash_create()
{
	hash_t *h;
	if((h = (hash_t *)malloc(sizeof(hash_t))) == NULL) {
		printf("malloc hash heap space failed\n");
		return NULL;
	}
 
	memset(h, 0, sizeof(hash_t));
 
	return h;
}
 
/*brife: release a hash table
 *
 * */
int hash_free(hash_t *h)
{
	if(h == NULL) {
		printf("param is invalid\n");
		return -1;
	}
 
	free(h);
 
	return 0;
}
 
 
/*brife: need search element insert to hash table
 *
 * */
int hash_insert(hash_t *h, datatype key)
{
	if(h == NULL) {
		printf("param is invalid\n");
		return -1;
	}
 
	link_list p, q;
 
	if((q = (link_list)malloc(sizeof(list_node))) == NULL) {
		printf("%s, alloc new node memery failed\n", __func__);
		return -1;
	}
 
	q->key = key;
	q->value = key % MOD;
	q->next = NULL;
 
	p = &(h->data[key % MOD]);
 
	while(p->next && p->next->key < q->key) {
		p = p->next;
	}
	q->next = p->next;
	p->next = q;
 
	return 0;
}
 
 
/*brife: specify data search
 *param:hash_t handle, search key
 *       
 * */
link_list hash_search(hash_t *h, datatype key)
{
	if(h == NULL) {
		printf("param is invalid\n");
		return NULL;
	}
	
	link_list p = &(h->data[key % MOD]);
 
	while(p->next != NULL && p->next->key != key) {
		p = p->next;
	}
	if(p->next == NULL) {
		return NULL;	
	} 
	return p->next;
 
}
 
int squence_search(int *arr, int arr_len, int obj_value)
{
	if(arr == NULL) {
		printf("param is invalid\n");
		return -1;
	}
 
	int i = 0;
	for(;i < arr_len; i++) {
		if(arr[i] == obj_value) {
			return i;
		}	
	}
 
	return -1;
}
 
 
int binary_search(int *arr, int arr_len, int obj_value)
{
	if(arr == NULL) {
		printf("param is invalid\n");
		return -1;
	}
 
	int low = 0, high = arr_len - 1, mid = (high + low) / 2;
	while(arr[mid] != obj_value) {
		if(arr[mid] < obj_value) {
			low = mid + 1;	
			mid = (low + high) / 2;
		} else {
			high = mid - 1;	
			mid = (low + high) / 2;
		}
	}
 
	return mid;
}
#include "hash.h"
 
int main(int argc, const char *argv[])
{
	datatype arr[] = {67, 7, 89, 6, 1, 198, 201};	
	int sort_arr[] = {1, 4, 6, 8, 9, 88};
 
	int i, arr_len = sizeof(arr) / sizeof(datatype);
	link_list ret = NULL;
	hash_t *h;
 
	if((h = hash_create()) == NULL) {
		printf("hash table create failed\n");
		return -1;
	}
 
	for(i = 0; i < arr_len; i++) {
		hash_insert(h, arr[i]);
	}
 
	printf("Please input a hope search data:");
	scanf("%d", &i);
 
	if((ret = hash_search(h, i)) == NULL) {
		printf("Not found\n");
	} else {
		printf("Found: key: %d, value: %d\n", ret->key, ret->value);
	}
 
	int r = squence_search(sort_arr, sizeof(sort_arr) / sizeof(int), 8);
	printf("squence_search: %d\n", r);
 
	r = binary_search(sort_arr, sizeof(sort_arr) / sizeof(int), 9);
	printf("squence_search: %d\n", r);
 
 
	return 0;
}

十、排序

1.冒泡

/* bubbling.c */
 
 
#include <stdio.h>
#include <stdlib.h>
 
#define N 15
 
void arrary_show(int *arr, int len)
{
	if(arr == NULL) {
		printf("param is invalid\n");
		return;
	}	
	int i = 0;
 
	for(;i < len; i++) {
		printf("%d ", arr[i]);
	}
	puts("");
}
 
void bubling_sort(int *arr, int len)
{
	if(arr == NULL) {
		printf("param is invalid\n");
		return;
	}	
	int i, j;
 
	for(i = 0; i < N; i++) {
		for(j = 0; j < N - 1 - i; j++) {
			if(arr[j] > arr[j + 1]) {
				arr[j] ^= arr[j + 1];        /* 交换两个元素的位置的异或写法 */
				arr[j + 1] ^= arr[j];
				arr[j] ^= arr[j + 1];
			}
		}
	}
	
}
 
int main(int argc, const char *argv[])
{
	int arr[N] = {0}; 	
	int i;
 
	srandom(10);
	for(i = 0; i < N; i++) {
		arr[i] = random() % 100;
	}
	arrary_show(arr, N);
 
	bubling_sort(arr, N);
	arrary_show(arr, N);
 
	return 0;
}

2.选择

#include <stdio.h>
#include <stdlib.h>
 
#define N 10
 
/*
算法思想: 每一轮找到一个最小值
*/
void select_sort(int *arr, int len)
{
	if(arr == NULL) {
		return;
	}
 
	int i, j, minindex;
	for(i = 0; i < N; i++) {
		minindex = i;
		for(j = i + 1; j < N; j++) {
			if(arr[j] < arr[minindex])
				minindex = j;
		}
		
		if(minindex != i) {
			arr[minindex] ^= arr[i];
			arr[i] ^= arr[minindex];
			arr[minindex] ^= arr[i];
		}
	}
}
 
 
int main(int argc, const char *argv[])
{
	int arr[N] = {0};
	int i;
 
	srandom(10);
	for(i = 0; i < N; i++) {
		arr[i] = random() % 100;
	}
 
	for(i = 0; i < N; i++) {
		printf("%d ", arr[i]);
	}
	puts("");
 
	select_sort(arr, N);
 
	for(i = 0; i < N; i++) {
		printf("%d ", arr[i]);
	}
	puts("");
 
 
	
	return 0;
}

3.插入

/*brife: insert sort
 *
 * */
void insert_sort(int arr[], int n) {
    int i, key, j;
    
    for (i = 1; i < n; i++) {
        key = arr[i];
        j = i - 1;
        
        // 将比 key 大的元素向右移动
        while (j >= 0 && arr[j] > key) {
            arr[j+1] = arr[j];
            j--;
        }
        
        arr[j+1] = key;
    }
}

4.快速排序

#include <stdio.h>
#include <stdlib.h>
 
#define N 10
 
void arr_foreach(int arr[], int arr_num)
{
	if(arr == NULL) {
		printf("%s, param is invalid\n", __func__);
		return ;
	}
 
	int i = 0;
	for(;i < arr_num; i++) {
		printf("%d ", arr[i]);
	}
	puts("");
}
 
int partion(int *arr, int low, int high)
{
	if(arr == NULL) {
		printf("%s, param is invalid\n", __func__);
		return -1;
	}
 
	int temp;
 
	while(low < high) {
		temp = arr[low];
		while(low < high && temp <= arr[high]) {
			high--;
		}
		arr[low] = arr[high];
		while(low < high && temp >= arr[low]) {
			low++;
		}
		arr[high] = arr[low];
	}
 
	arr[low] = temp;
 
	return low;
}
 
/*
找一个基准值, 基准值左边的比基准值小, 右边的比基准值大, 再将基准值左右两边的小数组调用同样的方法,递归
*/
int quick_sort(int *arr, int low, int high)
{
	if(arr == NULL) {
		printf("%s, param is invalid\n", __func__);
		return -1;
	}
 
	int t;
	
	if(low >= high)
		return 0;
	t = partion(arr, low, high);
 
	quick_sort(arr, low, t - 1);
	quick_sort(arr, t + 1, high);
 
	return 0;
 
}
 
int main(int argc, const char *argv[])
{
	int arr[N] = {0};
	int i;
 
	srandom(10);
	for(i = 0; i < N; i++) {
		arr[i] = random() % 100;
	}
 
	printf("quick sort before: ");
	arr_foreach(arr, N);
 
	quick_sort(arr, 0, N - 1);
 
	printf("quick sort after: ");
	arr_foreach(arr, N);
	
	return 0;
}

5.库函数的qsort

#include <stdio.h>
#include <stdlib.h>
 
#define N 10
 
int compare(const void *p1, const void *p2)
{
	return (*(int *)p1 - *(int *)p2);
}
 
int main(int argc, const char *argv[])
{
	int arr[N] = {0};
	int i;
	
	srandom(10);
	for(i = 0; i < N; i++) {
		arr[i] = random() % 100;
	}
 
	for(i = 0; i < N; i++) {
		printf("%d ", arr[i]);
	}
	puts("");
 
	qsort(arr, N, sizeof(int), compare);
 
	for(i = 0; i < N; i++) {
		printf("%d ", arr[i]);
	}
	puts("");
	
	return 0;
}

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@daiwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值