<3> 单链表的各种操作(创建、增加、删除、修改、查找、逆序、判空、置空等)

来源:互联网 发布:快手直播配音软件 编辑:程序博客网 时间:2024/05/29 06:42

1 . 链表的创建

1)首先声明三个结构体指针变量(head、p1、p2),其中,一个是头结点,剩余的两个用来连接。

2)给p1开辟内存空间,代表第一个结点的地址,并且给第一个结点的数据域中的数据赋值。


3)循环创建(假设有N个结点需要创建)的过程。需要分情况,当我们的头结点并没有被连接到任何创建的结点上时,需要将head连接到,同时需要将p2也指向p1,这是因为当我们在将head连接上之后,之后的连接就需要p2和p1来进行完成,不需要head了。如下图:


这是在循环创建时的几个过程。记得每开辟一个空间,需要给结构体中的数据赋值,即每一个结点赋值。

4)创建结束后,需要将p2的指针域指向NULL,代表整个链表结束,并且记得释放p1,因为p1的作用仅仅是为我们创建新的结点。

2 . 判空

链表的最后一个指针域是指向NULL的,所以我们只需要判断head是不是指向NULL即可,如果是,代表链表是空的,如果不是,代表链表有数据。

3 . 置空

同样,我们需要将头指针指向NULL即可。

4 . 删除


如图想要把中间的结点删除,需要将第一个结点的指针域指向第三个结点的地址,就可以实现在链表中将第二个结点删除。

5 . 增加、修改、逆序等见代码的详解。

6 . 详细代码

1)Head.h文件

#pragma once#include <stdio.h>#include <malloc.h>#include <stdlib.h>#include <iostream>//! \brief 一个关于“学生”的结构体类型typedef struct Student{// 数据域(存储数据)int  _age;//!< 年龄char _name[20];//!< 姓名char _gender;//!< 性别// 指针域(存储下一个节点的地址)Student *next;}LinkList;/*这里是一些基本的链表操作的函数声明*/// 创建一个链表LinkList* create(unsigned int Number);// 判断链表是否为空bool IsEmpty(LinkList L);// 将链表置空void MakeLinkList(LinkList L);// 根据值查询位置// 1:年龄 2:名字 3:性别int Find1(LinkList *L, int Age);int Find2(LinkList *L, char *Name);int Find3(LinkList *L, char Gender);// 删除某个节点bool Delete(LinkList *L, char *Name);// 增加一个节点bool Push_Back(LinkList *L, LinkList *LNew);// 修改一个节点bool Modify(LinkList *L, char *Name);// 打印整个链表void PrintLinkList(LinkList* L);// 逆序整个链表LinkList* Reverse(LinkList *L);
2)Source.cpp文件

#include "Header.h"/*这里是一些基本的链表操作的函数实现*/LinkList* create(unsigned int Number){// 声明三个结构体( 其中head是头节点,p1为临时节点,p2是辅助节点 )LinkList *head, *p1 = NULL, *p2 = NULL;// 使得P1、P2指向空间大小为sizeof(LinkList)的内存空间p1 = (LinkList*)malloc(sizeof(LinkList));// 初始化head为NULLhead = NULL;// 初始化第一个节点的数据std::cin >> p1->_name >> p1->_age >> p1->_gender;// 循环创建、连接、初始化数据for (size_t i = 0; i < Number - 1;){// 连接节点if (head == NULL){head = p1;p2 = p1;}else{// 创建新的节点,并初始化新的节点p1 = (LinkList*)malloc(sizeof(LinkList));//scanf_s("%s %d %c", &p1->_name, &p1->_age, &p1->_gender);std::cin >> p1->_name >> p1->_age >> p1->_gender;p2->next = p1;p2 = p1;// addi++;}}// 使p2->next指向空,代表链表结束p2->next = NULL;// 释放临时的p1p1 = NULL;free(p1);return head;}bool IsEmpty(LinkList L){return L.next == NULL;}void MakeLinkList(LinkList L){L.next = NULL;}int Find1(LinkList *L, int Age){int Location = 0;LinkList *P = L->next;while (P!= NULL&&P->_age != Age){P = P->next;Location++;}return Location;}int Find2(LinkList *L, char *Name){int Location = 0;LinkList *P = L;while (P!= NULL&&strcmp(P->_name,Name)){P = P->next;Location++;}return Location;}int Find3(LinkList *L, char Gender){int Location = 0;LinkList *P = L->next;while (P!=NULL&&P->_gender != Gender){P = P->next;Location++;}return Location;}bool Delete(LinkList *L, char *Name){// 两个临时的指针,其中第一个指针是保存目标节点的上一个节点LinkList *TempPointer1 = L;LinkList *TempPointer2 = NULL;while (strcmp(TempPointer1->_name,Name) && TempPointer1 != NULL){TempPointer2 = TempPointer1;TempPointer1 = TempPointer1->next;}if (TempPointer1 != NULL){TempPointer2->next = TempPointer1->next;return true;}return false;}bool Push_Back(LinkList *L, LinkList *LNew){// 将LNew加到L中// 尾插while (L!=NULL){if (L->next == NULL){L->next = LNew;break;}L = L->next;}return true;}bool Modify(LinkList *L, char *Name){while (strcmp(L->_name,Name) && L!=NULL){L = L->next;}if (L != NULL){L->_age = 100;L->_gender = 'm';return true;}return false;}void PrintLinkList(LinkList *L){while (L!=NULL){std::cout << L->_name << " " << L->_age << " " << L->_gender << std::endl;L = L->next;}}LinkList* Reverse(LinkList *L){LinkList *PreLinkList = NULL;LinkList *Next;while (L!=NULL){Next = L->next;L->next = PreLinkList;PreLinkList = L;L = Next;}return PreLinkList;}
3)main.cpp文件

#include "Header.h"int main(){// 初始化并打印//----------------------------------------------------------------LinkList* head = create(3);std::cout << "Origin : " << std::endl;PrintLinkList(head);// 我是分割线std::cout << "-----------------------------------------------------" << std::endl;// 1 . 增//----------------------------------------------------------------LinkList* NewLinkedList = create(2);Push_Back(head, NewLinkedList);std::cout << "Added : " << std::endl;PrintLinkList(head);// 我是分割线std::cout << "-----------------------------------------------------" << std::endl;// 2 . 删//----------------------------------------------------------------Delete(head, "test2");std::cout << "Deleted : " << std::endl;PrintLinkList(head);// 我是分割线std::cout << "-----------------------------------------------------" << std::endl;// 3 . 改//----------------------------------------------------------------Modify(head, "test1");std::cout << "Modified : " << std::endl;PrintLinkList(head);// 我是分割线std::cout << "-----------------------------------------------------" << std::endl;// 4 . 查//----------------------------------------------------------------int Location = Find2(head, "test1");std::cout << "Finded : " << Location << std::endl;// 我是分割线std::cout << "-----------------------------------------------------" << std::endl;// 5 . 逆LinkList* New = Reverse(head);std::cout << "Resversed : " << std::endl;PrintLinkList(New);std::cout << "---------------------Finished------------------------" << std::endl;system("pause");return 0;}

阅读全文
0 0
原创粉丝点击