1.0、C语言数据结构——单链表尾插法练习
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
void menu() {
printf("********************************************\n");
printf("******** 1.添加 2.查询 ********\n");
printf("******** 0.退出 ********\n");
printf("********************************************\n");
}
typedef struct Student {
char name[20];
char sex[10];
}Student;
typedef struct Node {
Student* data; //数据域
struct Node* next; //指针域
}Node;
typedef struct List {
Node* firstNode; //指向头结点
Node* LastNode; //指向尾结点
int CurSize; //当前链表的结点数
}List;
//链表信息初始化
void InitList(List* list) {
list->CurSize = 0; //目前链表中结点的数量
list->firstNode = NULL; //头结点指向空
list->LastNode = NULL; //尾结点指向空
}
//头结点初始化
void InitHeadNode(List* list) {
Node* HeadNode = (Node*)malloc(sizeof(Node));//动态开辟一块空间给头结点
assert(HeadNode != NULL);
Student* student = (Node*)malloc(sizeof(Student));//给头结点数据域动态开辟一块空间
assert(student != NULL);
HeadNode->data = student;//让头结点的数据域指针管理维护这块空间
HeadNode->next = NULL;//让头结点的指针域指向空(因为此时头结点也是尾结点)
list->firstNode = HeadNode;
list->LastNode = HeadNode;
list->CurSize++;
}
//尾插法——创建新结点
void creatNewNode(List* list) {
Node* newNode = (Node*)malloc(sizeof(Node));//动态开辟一块空间给新结点
assert(newNode != NULL);
Student* student = (Node*)malloc(sizeof(Student));//给新结点数据域动态开辟一块空间
assert(student != NULL);
newNode->data = student;//让新结点的数据域指针管理维护这块空间
newNode->next = NULL;
list->LastNode->next = newNode;//让之前的尾结点指向新的尾结点
list->LastNode = newNode; //让新结点成为新的尾结点
list->CurSize++; //链表结点数量自增 1
printf("请输入姓名:> ");
scanf("%s",newNode->data->name);
printf("请输入性别:> ");
scanf("%s",newNode->data->sex);
}
//查询出链表所有的信息
void ShowAllNodeInfos(List* list) {
Node* tmp = list->firstNode->next; //创建一个临时结点指针变量tmp, 用来存放头结点指针域
printf("\t%-20s\t%-10s\n","姓名","性别");
while (tmp != NULL) {
//我的头结点不存放数据域内容,所以直接从第二个结点开始遍历
printf("\t%-20s\t%-10s\n", tmp->data->name, tmp->data->sex);
tmp = tmp->next;//让 tmp 存放当前遍历结点的指针域
}
}
//释放空间
void ListFree(List* list) {
assert(list != NULL);
Node* tmp = list->firstNode; //创建临时变量 tmp 存放指向头结点的指针
while(tmp != NULL) {
Node* tmpNext = tmp->next; //创建一个临时指针变量 tmpNext 用来存放当前遍历结点的指针域
free(tmp->data);
tmp->data = NULL;
free(tmp);
tmp = NULL;
tmp = tmpNext; //让指向当前结点的指针 存放 当前遍历结点的指针域
}
}
int main() {
//链表初始化
List list = { 0 };
List* pl = &list;
InitList(&list);
//头结点初始化
InitHeadNode(&list);
int input = 0;
do {
menu();
printf("请选择:> ");
scanf("%d",&input);
switch (input)
{
case 1:
creatNewNode(&list);
break;
case 2:
ShowAllNodeInfos(&list);;
break;
case 0:
printf("退出成功");
break;
default:
break;
}
} while (input);
//释放掉动态开辟的空间
ListFree(&list);
printf("动态空间内存已释放~");
return 0;
}