数据结构与算法 第四天-队列与栈的逻辑与单向循环链表
建议边看图,边看代码,不然还是理解不容易
第一章 数据结构 队列 代码实现(先进先出)
先进先出:第一个放在第一位,其余依次放在后面,取出时遍历从第一个拿
联合函数inline:适合代码简短且固定的函数 静态函数static:防止函数重名,作用域只在本.c文件内
出队 入队
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct list_node{
int data;
struct list_node *next;
}node_t;
node_t *request_queue_node(void)
{
node_t *new_node;
new_node = malloc(sizeof(node_t));
if(new_node == NULL)
{
perror("申请链表节点失败");
return NULL;
}
new_node->next = NULL;
return new_node;
}
static inline void enqueue(node_t *list_head, node_t *insert_node)
{
node_t *pos;
for(pos=list_head; pos->next != NULL; pos=pos->next);
pos->next = insert_node;
}
void show_queue(node_t *list_head)
{
node_t *pos;
printf("队列已有数据:");
for(pos=list_head->next; pos!=NULL; pos = pos->next)
{
printf("%d ", pos->data);
}
printf("\n");
}
bool is_empty(node_t *head)
{
return head->next == NULL;
}
node_t *dequece(node_t *list_head)
{
if(is_empty(list_head))
return NULL;
node_t *dequece_node;
dequece_node = list_head->next;
list_head->next = dequece_node->next;
return dequece_node;
}
void destroy_queue(node_t *list_head)
{
node_t *pos, *next;
pos = list_head;
do{
next = pos->next;
free(pos);
pos=next;
}while(pos!=NULL);
}
int main(void)
{
int input_value;
node_t *list_head, *new_node, *get_node;
list_head = request_queue_node();
if(list_head == NULL)
return -1;
list_head->data = -1;
while(1)
{
scanf("%d", &input_value);
if(input_value > 0)
{
new_node = request_queue_node();
new_node->data = input_value;
enqueue(list_head, new_node);
}
else if(input_value < 0)
{
get_node = dequece(list_head);
if(get_node != NULL)
{
printf("出队节点为%d\n", get_node->data);
free(get_node);
}
else
{
printf("队列已空\n");
}
}
else
break;
show_queue(list_head);
}
destroy_queue(list_head);
return 0;
}
第二章 数据结构 栈和队列合并 代码实现(先进后出)
先进后出:先进的放在后面,下一次插入放在他前面,以此类推
两条栈合成一条队列
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct list_node{
int data;
struct list_node *next;
}node_t;
node_t *request_list_node(void)
{
node_t *new_node;
new_node = malloc(sizeof(node_t));
if(new_node == NULL)
{
perror("申请链表节点失败");
return NULL;
}
new_node->next = NULL;
return new_node;
}
static inline void in_stack(node_t *list_head, node_t *insert_node)
{
insert_node->next = list_head->next;
list_head->next = insert_node;
}
void show_list_data(node_t *list_head)
{
node_t *pos;
printf("队列已有数据:");
for(pos=list_head->next; pos!=NULL; pos = pos->next)
{
printf("%d ", pos->data);
}
printf("\n");
}
bool is_empty(node_t *head)
{
return head->next == NULL;
}
node_t *out_stack(node_t *list_head)
{
if(is_empty(list_head))
return NULL;
node_t *get_stack_node;
get_stack_node = list_head->next;
list_head->next = get_stack_node->next;
get_stack_node->next = NULL;
return get_stack_node;
}
#define dequeue(list_head) out_stack(list_head)
static inline void enqueue(node_t *list_head, node_t *insert_node)
{
node_t *pos;
for(pos=list_head; pos->next != NULL; pos=pos->next);
pos->next = insert_node;
}
void destroy_list(node_t *list_head)
{
node_t *pos, *next;
pos = list_head;
do{
next = pos->next;
free(pos);
pos=next;
}while(pos!=NULL);
}
int main(void)
{
node_t *src1_list, *src2_list, *new_node;
node_t *queue_list;
node_t *get_src1_node, *get_src2_node;
int i;
int src1_data[] = {2, 5, 8, 13, 18};
int src2_data[] = {1, 3, 4, 7, 9, 10, 19};
src1_list = request_list_node();
src2_list = request_list_node();
queue_list = request_list_node();
for(i=sizeof(src1_data)/sizeof(int)-1; i>=0; i--)
{
new_node = request_list_node();
new_node->data = src1_data[i];
in_stack(src1_list, new_node);
}
for(i=sizeof(src2_data)/sizeof(int)-1; i>=0; i--)
{
new_node = request_list_node();
new_node->data = src2_data[i];
in_stack(src2_list, new_node);
}
show_list_data(src1_list);
show_list_data(src2_list);
get_src1_node = out_stack(src1_list);
get_src2_node = out_stack(src2_list);
while(1)
{
if(get_src1_node->data < get_src2_node->data)
{
enqueue(queue_list, get_src1_node);
get_src1_node = out_stack(src1_list);
}
else
{
enqueue(queue_list, get_src2_node);
get_src2_node = out_stack(src2_list);
}
show_list_data(queue_list);
sleep(3);
if(get_src1_node == NULL)
{
enqueue(queue_list, get_src2_node);
while((get_src2_node = out_stack(src2_list))!= NULL)
{
enqueue(queue_list, get_src2_node);
}
break;
}
else if(get_src2_node == NULL)
{
enqueue(queue_list, get_src1_node);
while((get_src1_node = out_stack(src1_list))!= NULL)
{
enqueue(queue_list, get_src1_node);
}
break;
}
}
show_list_data(queue_list);
return 0;
}
第三章 学生信息单向链表完整实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
struct student_info{
char name[4096];
short age;
float height;
};
typedef struct list_node{
struct student_info data;
struct list_node *next;
}node_t;
node_t *request_link_list_node(void)
{
node_t *new_node;
new_node = malloc(sizeof(node_t));
if(new_node == NULL)
{
perror("申请链表节点失败");
return NULL;
}
new_node->next = NULL;
return new_node;
}
static inline void insert_node_link_list(node_t *refer_node, node_t *insert_node)
{
insert_node->next = refer_node->next;
refer_node->next = insert_node;
}
void display_link_node_data(node_t *list_head)
{
node_t *pos;
printf("链表现有数据:\n");
for(pos=list_head->next; pos!=NULL; pos = pos->next)
{
printf("学生信息:名字=%s, 年龄=%hd, 身高=%.2f\n", pos->data.name, pos->data.age, pos->data.height);
}
printf("____________________________\n");
}
bool is_empty(node_t *head)
{
return head->next == NULL;
}
int remove_list_next_node(node_t *refer_node)
{
if(is_empty(refer_node))
{
fprintf(stderr, "表格已经空了\n");
return -1;
}
node_t *rm_node;
rm_node = refer_node->next;
refer_node->next = rm_node->next;
free(rm_node);
return 0;
}
void destroy_link_list(node_t *list_head)
{
node_t *pos;
while(!is_empty(list_head))
{
printf("free %s\n", list_head->next->data.name);
remove_list_next_node(list_head);
}
free(list_head);
}
node_t *find_link_node(node_t *list_head, const char *find_name)
{
node_t *pos;
for(pos=list_head->next; pos!=NULL; pos = pos->next)
{
if(strcmp(pos->data.name, find_name) == 0)
{
return pos;
}
}
return NULL;
}
int register_student_info(node_t *list_head)
{
node_t *new_node;
new_node = request_link_list_node();
if(new_node == NULL)
{
perror("申请内存出错");
return -1;
}
printf("开始注册学生信息:\n");
printf("请输入学生名字:\n");
scanf("%s", new_node->data.name);
printf("请输入学生年龄:\n");
scanf("%hd", &new_node->data.age);
printf("请输入学生身高:\n");
scanf("%f", &new_node->data.height);
insert_node_link_list(list_head, new_node);
return 0;
}
node_t *find_student_info(node_t *list_head)
{
char name[16];
node_t *find_node;
printf("请输入需要搜索的学生名字\n");
scanf("%s", name);
find_node = find_link_node(list_head, name);
if(find_node != NULL)
{
printf("寻找到的学生信息:名字=%s, 年龄=%hd, 身高=%.2f\n",
find_node->data.name, find_node->data.age, find_node->data.height);
}
else
{
printf("找不到该学生信息\n");
}
return find_node;
}
int remove_student_info(node_t *list_head)
{
char name[16];
node_t *prev, *pos;
printf("请输入需要开除的学生名字\n");
scanf("%s", name);
for(prev=list_head, pos=list_head->next; pos!=NULL; prev=pos, pos=pos->next)
{
if(strcmp(pos->data.name, name) == 0)
{
remove_list_next_node(prev);
return 0;
}
}
fprintf(stderr, "找不到你需要删除的学生信息\n");
return -1;
}
int main(void)
{
int input_cmd;
node_t *list_head;
list_head = request_link_list_node();
if(list_head == NULL)
goto request_list_err;
while(1)
{
printf("欢迎进入学生信息系统:\n");
printf("输入1:录入学生信息\n");
printf("输入2:打印学生信息:\n");
printf("输入3:寻找指定学生信息\n");
printf("输入4:开除指定学生\n");
printf("输入5:退出整个系统\n");
scanf("%d", &input_cmd);
switch(input_cmd)
{
case 1:
register_student_info(list_head);
break;
case 2:
display_link_node_data(list_head);
break;
case 3:
find_student_info(list_head);
break;
case 4:
remove_student_info(list_head);
break;
case 5:
goto system_exit;
default:
break;
}
}
system_exit:
destroy_link_list(list_head);
return 0;
request_list_err:
return -1;
}
第四章 单向非循环链表
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct list_node{
int data;
struct list_node *next;
}node_t;
node_t *request_link_list_node(void)
{
node_t *new_node;
new_node = malloc(sizeof(node_t));
if(new_node == NULL)
{
perror("申请链表节点失败");
return NULL;
}
new_node->next = NULL;
return new_node;
}
static inline void insert_node_link_list(node_t *refer_node, node_t *insert_node)
{
insert_node->next = refer_node->next;
refer_node->next = insert_node;
}
void display_link_node_data(node_t *list_head)
{
node_t *pos;
printf("链表现有数据:");
for(pos=list_head->next; pos!=NULL; pos = pos->next)
{
printf("%d ", pos->data);
}
printf("\n");
}
bool is_empty(node_t *head)
{
return head->next == NULL;
}
int remove_list_next_node(node_t *refer_node)
{
if(is_empty(refer_node))
{
fprintf(stderr, "表格已经空了\n");
return -1;
}
node_t *rm_node;
rm_node = refer_node->next;
refer_node->next = rm_node->next;
free(rm_node);
return 0;
}
void destroy_link_list(node_t *list_head)
{
node_t *pos;
while(!is_empty(list_head))
{
printf("free %d\n", list_head->next->data);
remove_list_next_node(list_head);
}
free(list_head);
}
node_t *find_link_node(node_t *list_head, int find_data)
{
node_t *pos;
for(pos=list_head->next; pos!=NULL; pos = pos->next)
{
if(pos->data == find_data)
{
return pos;
}
}
return NULL;
}
void sequence_insert_node_to_list(node_t *list_head, node_t *insert_node)
{
node_t *prev, *pos;
for(prev=list_head, pos=list_head->next; pos!=NULL; prev=pos, pos=pos->next)
{
if(pos->data > insert_node->data)
{
break;
}
}
insert_node_link_list(prev, insert_node);
}
int main(void)
{
int input_value;
node_t *list_head, *new_node;
list_head = request_link_list_node();
if(list_head == NULL)
return -1;
list_head->data = -1;
while(1)
{
scanf("%d", &input_value);
if(input_value > 0)
{
new_node = request_link_list_node();
new_node->data = input_value;
sequence_insert_node_to_list(list_head, new_node);
display_link_node_data(list_head);
}
else if(input_value < 0)
{
remove_list_next_node(list_head);
display_link_node_data(list_head);
}
else
break;
}
destroy_link_list(list_head);
return 0;
}
第五章 单向循环链表【宏函数会玩吗?】
循环代表要收尾相连,一个圈 当头节点的下一个指向自己,就代表没数据了
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct list_node{
int data;
struct list_node *next;
}node_t;
#define list_for_each(head, pos) for(pos=head->next; pos!=head; pos=pos->next)
#define list_for_each_safe(head, pos, n) for(pos=head->next, n=pos->next; pos!=head; pos=n, n=n->next)
node_t *request_link_list_node(void)
{
node_t *new_node;
new_node = malloc(sizeof(node_t));
if(new_node == NULL)
{
perror("申请链表节点失败");
return NULL;
}
new_node->next = new_node;
return new_node;
}
static inline void insert_node_link_list(node_t *refer_node, node_t *insert_node)
{
insert_node->next = refer_node->next;
refer_node->next = insert_node;
}
void display_link_node_data(node_t *list_head)
{
node_t *pos;
printf("链表现有数据:");
list_for_each(list_head, pos)
{
printf("%d ", pos->data);
}
printf("\n");
}
bool is_empty(node_t *head)
{
return head->next == head;
}
int remove_list_next_node(node_t *refer_node)
{
if(is_empty(refer_node))
{
fprintf(stderr, "表格已经空了\n");
return -1;
}
node_t *rm_node;
rm_node = refer_node->next;
refer_node->next = rm_node->next;
free(rm_node);
return 0;
}
void destroy_link_list(node_t *list_head)
{
node_t *pos;
node_t *n;
list_for_each_safe(list_head, pos, n)
{
printf("free %d \n", pos->data);
free(pos);
}
free(list_head);
}
node_t *find_link_node(node_t *list_head, int find_data)
{
node_t *pos;
list_for_each(list_head, pos)
{
if(pos->data == find_data)
{
return pos;
}
}
return NULL;
}
void sequence_insert_node_to_list(node_t *list_head, node_t *insert_node)
{
node_t *prev, *pos;
for(prev=list_head, pos=list_head->next; pos!=list_head; prev=pos, pos=pos->next)
{
if(pos->data > insert_node->data)
{
break;
}
}
insert_node_link_list(prev, insert_node);
}
int main(void)
{
int input_value;
node_t *list_head, *new_node;
list_head = request_link_list_node();
if(list_head == NULL)
return -1;
list_head->data = -1;
while(1)
{
scanf("%d", &input_value);
if(input_value > 0)
{
new_node = request_link_list_node();
new_node->data = input_value;
sequence_insert_node_to_list(list_head, new_node);
display_link_node_data(list_head);
}
else if(input_value < 0)
{
remove_list_next_node(list_head);
display_link_node_data(list_head);
}
else
break;
}
destroy_link_list(list_head);
return 0;
}
|