1.链表常用函数
1.malloc函数
malloc函数在内存之中动态分配一块size大小的内存空间,它是为链表操作的基础。
void *malloc(unsigned int size);
2.calloc函数
calloc函数用在内存中动态分配n个长度为size的连续空间。
void *calloc(unsigned n,unsigned size);
3.free函数
free函数用来进行释放指针ptr指向的内存区域,使该部分内存可以被其它变量使用。
void free(void *ptr);
4.realloc函数
realloc函数的功能将对应ptr指针指向的内存空间大小改为size;
void *realloc(void *ptr,size_t size);
2.链表使用办法
1.头插法
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
// 创建新节点
struct Node* newNode(int data)
{
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->next = NULL;
return node;
}
// 在链表头部插入节点
void insertAtHead(struct Node** head, int data)
{
struct Node* newNode = createNode(data);
newNode->next = *head;
*head = newNode;
}
// 打印链表数据
void printList(struct Node* head)
{
struct Node* temp = head;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
struct Node* head = NULL;
// 在链表头部插入节点
insertAtHead(&head, 3);
insertAtHead(&head, 2);
insertAtHead(&head, 1);
printf("链表数据:");
printList(head);
return 0;
}
2.尾插法
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
// 创建新节点
struct Node* newNode(int data) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->next = NULL;
return node;
}
// 在链表尾部插入节点
void insertAtTail(struct Node** head, int data) {
struct Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
} else {
struct Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}
// 打印链表数据
void printList(struct Node* head) {
struct Node* temp = head;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
struct Node* head = NULL;
// 在链表尾部插入节点
insertAtTail(&head, 1);
insertAtTail(&head, 2);
insertAtTail(&head, 3);
printf("链表数据:");
printList(head);
return 0;
}
3.双向链表
双向链表(Doubly Linked List)是一种常见的链表数据结构,它与单向链表类似,但每个节点都有一个指向前一个节点的指针(prev),除了指向后一个节点的指针(next)。
双向链表中的每个节点包含三个部分:
- 数据(可以是任意类型的数据)。
- 指向前一个节点的指针(prev)。
- 指向后一个节点的指针(next)。
通过这两个指针,每个节点可以在链表中的前后移动。
相较于单向链表,双向链表的优点在于:
- 可以从任意方向遍历链表:由于每个节点都有一个指向前一个节点的指针,所以可以从头到尾或者从尾到头遍历链表。
- 删除操作更高效:删除节点时,不需要像单向链表那样找到待删除节点的前一个节点,而是直接更新前后节点的指针即可。
然而,双向链表的缺点是占用更多的内存空间,因为每个节点需要存储额外的指针。
双向链表提供了更灵活的操作,使得在某些场景下更为方便。例如,在需要频繁插入和删除节点的情况下,双向链表能够更高效地执行这些操作。
#include <stdio.h>
#include <stdlib.h>
// 双向链表节点结构
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
// 在链表头部插入节点
void insertAtHead(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->prev = NULL;
if (*head != NULL) {
(*head)->prev = newNode;
}
newNode->next = *head;
*head = newNode;
}
// 在链表尾部插入节点
void insertAtTail(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
if (*head == NULL) {
newNode->prev = NULL;
*head = newNode;
return;
}
struct Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
// 打印链表数据(正向)
void printForward(struct Node* head) {
struct Node* temp = head;
printf("正向打印链表数据:");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
// 打印链表数据(逆向)
void printBackward(struct Node* head) {
struct Node* temp = head;
if (temp == NULL) {
return;
}
while (temp->next != NULL) {
temp = temp->next;
}
printf("逆向打印链表数据:");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->prev;
}
printf("\n");
}
int main() {
struct Node* head = NULL;
// 在链表头部插入节点
insertAtHead(&head, 3);
insertAtHead(&head, 2);
insertAtHead(&head, 1);
// 在链表尾部插入节点
insertAtTail(&head, 4);
insertAtTail(&head, 5);
// 正向打印链表数据
printForward(head);
// 逆向打印链表数据
printBackward(head);
return 0;
}
举个函数学生信息的链表函数
#include<stdio.h>
#include<stdlib.h>
struct student
{
int num;
char name[64];
float score;
struct student* pnext;
};
//全局定义
void input(void);//进行成绩的录入
void delect(void);//进行学生信息的删除
void revise(void);//进行学生信息的修改
void find(void);//进行学生信息的查找
void show(void);//显示学生信息
struct student *phead=NULL;//全局定义链表头函数
int main()
{
int choice=0;
face:
while(1)
{
printf("********学生管理系统********\n");
printf("*****1.进行学生信息记录*****\n");
printf("*****2.进行学生信息删除*****\n");
printf("*****3.进行学生信息修改*****\n");
printf("*****4.进行学生信息查找*****\n");
printf("*****5.返回学生信息界面*****\n");
printf("*****6.退出学生管理系统*****\n");
printf("请输入您所需要进行的操作\n");
scanf("%d",&choice);
if((choice>0&&choice<7)||(choice=99))
{
if(choice==1)
{
input();//记录
}
else if(choice==2)
{
delect();//删除
}
else if(choice==3)
{
revise();//选择
}
else if(choice==4)
{
find();//查找
}
else if(choice==5)
{
printf("正在返回学生主界面......\n");
goto face;
}
else if(choice==6)
{
printf("正在退出学生信息管理系统......\n");
goto over;
}
else if(choice==99)
{
show();
}
}
else
{
printf("您所输入的数字不合规则\n");
goto face;
}
}
over:
printf("谢谢使用\n");
}
void input(void)//进行成绩的录入
{
struct student *pnew=NULL;
struct student *ptemp=phead;
pnew=(struct student*)malloc(sizeof(struct student));//给新录入的数开辟空间
pnew->pnext=NULL;
printf("学号\n");
scanf("%d",&pnew->num);
printf("姓名\n");
scanf("%s",pnew->name);
printf("成绩\n");
scanf("%f",&pnew->score);
if(phead==NULL)
{
phead=pnew;
}
else
{
while(ptemp->pnext!=NULL)
{
ptemp=ptemp->pnext;
}
ptemp->pnext=pnew;
}
return;
}
void delect(void)//进行学生信息的删除
{
int num1=0;
struct student *ptemp=phead;
struct student *pdel=NULL;
printf("请输入您所需要进行删除的学号\n");
scanf("%d",&num1);
if (phead==NULL)
{
printf("该空间并不存在该学生\n");
return;
}
if (ptemp->num==num1)//判定第一个节点是否为要进行删除的节点
{
pdel=phead;
phead=phead->pnext;
free(pdel);
printf("已经删除了对应学号的学生\n");
return ;
}
while(ptemp->pnext!=NULL)//如果不是第一个节点
{
if(ptemp->pnext->num==num1)
{
pdel=ptemp->pnext;
ptemp->pnext=ptemp->pnext->pnext;
free(pdel);
printf("已经删除了对应学号的学生\n");
return ;
}
ptemp=ptemp->pnext;
}
printf("查无此人\n");
}
void revise(void)//进行学生信息的修改
{
int num1;
struct student *pnew=phead;
printf("正在进行修改中......\n");
printf("请输入您想所需要进行修改的学生学号\n");
scanf("%d",&num1);
while(pnew!=NULL)
{
if(pnew->num==num1)
{
printf("请输入您所需要进行修改的信息\n");
printf("学号\n");
scanf("%d",&pnew->num);
printf("姓名\n");
scanf("%s",pnew->name);
printf("成绩\n");
scanf("%f",&pnew->score);
printf("修改成功\n");
break;
}
pnew=pnew->pnext;
}
if (pnew=NULL)
{
printf("未查到需要修改的学生\n");
}
}
void find(void)//进行学生信息的查找
{
int num1;
struct student *pfind=phead;
printf("正在进行查找中......\n");
printf("请输入您想所需要进行查找的学生学号\n");
scanf("%d",&num1);
while(pfind!=NULL)
{
if(pfind->num==num1)
{
printf("学号\t姓名\t成绩\n");
printf("%d\t",pfind->num);
printf("%s\t",pfind->name);
printf("%.2f\n",pfind->score);
break;
}
pfind=pfind->pnext;
}
if (pfind=NULL)
{
printf("未查到该学生\n");
}
}
void show(void)//显示学生信息
{
struct student *ptemp=NULL;//进行中间变量的定义
int ilndex=0;
printf("*****所有学生信息如下*****\n");
printf("\n");
printf("学号\t姓名\t成绩\n");
ptemp=phead;
while(ptemp!=NULL)
{
printf("%d\t",ptemp->num);
printf("%s\t",ptemp->name);
printf("%.2f\n",ptemp->score);
ptemp=ptemp->pnext;
ilndex++;
}
printf("一共录入了%d个同学\n",ilndex);
}