在数据结构中,顺序表和链表的增删查改是基础的知识,下边是我学习链表的一些心得。
链表的增删查改。(后附完整代码实现)
尾插:(思路:先创建一个新的结点,让链表遍历到最后一个结点,让最后一个节点的next指向下一个newNode即可)
代码实现:
//尾插一个元素到链表中
void LinkListPushBack(LinkNode** head,LinkType value){
if(head == NULL){
return;
}
if(*head == NULL){
*head = CreatNewNode(value);
return;
}
LinkNode *phead = *head;
while(phead->next){
phead = phead->next;
}
phead->next = CreatNewNode(value);
return;
}
尾删一个元素:
思路:定义两个指针,使其遍历链表,同时++,当cur->next指向为空的时候,停止,销毁cur指向的节点。
代码实现:
void LinkListPopBack(LinkNode** head){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
return;
//空链表
}
if((*head)->next == NULL){
DestoryNode(*head);
*head == NULL;
return;
}
LinkNode* pre = NULL;
LinkNode* cur = *head;
while(cur->next != NULL){
pre = cur;
cur = cur->next;
}
pre->next = NULL;
DestoryNode(cur);
return;
}
头插和头删:
头插思维:创建一个新的节点,使其next指向头结点,再将NewNode成为头结点。
头删思维:将头结点变为头结点的下一个节点,销毁之前的头结点即可
代码实现:
//头插一个元素
void LinkListPushHead(LinkNode** head,LinkType value){
if(head ==NULL){
return;
}
LinkNode* NewNode = CreatNewNode(value);
NewNode->next = *head;
*head = NewNode;
return;
}
//头删一个元素
void LinkListPopHead(LinkNode** head){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
//空链表
return;
}
LinkNode* cur = *head;
*head = (*head)->next;
DestoryNode(cur);
return;
}
在元素之后插入元素:
与尾插的思维相差不多,但是不用遍历,直接使其创建的节点指向就行。但是需要注意的是,需要先让新结点指向下一个节点,不然pos的下一个知不道正确的地址。
代码实现:
//在下标为pos后插入值
void LinkListInsert(LinkNode* pos,LinkType value){
if(pos == NULL){
return;
}
LinkNode* NewNode = CreatNewNode(value);
NewNode->next = pos->next;
pos->next = NewNode;
return;
}
在元素之前插入元素:
思路:这个实现起来还是挺有意思的,要实现一种偷梁换柱的思维。先实现元素之后的插入,然后进行值交换,即可得到结果。
代码实现:
//在下标为pos前插入值
void LinkListInsertBef(LinkNode** head,LinkNode* pos,LinkType value){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
return;
//空链表
}
if(pos == NULL){
return;
}
LinkNode* NewNode = CreatNewNode(value);
NewNode->next = pos->next;
pos->next = NewNode;
NewNode->data = pos->data;
pos->data = value;
return;
}
后边的查找和删除就直接写代码了:
//实现删除指定的元素
void LinkListDelVal(LinkNode** head,LinkType value){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
//空指针
return;
}
LinkNode* cur = *head;
LinkNode* pos = LinkListFind(*head,value);
for(; cur != NULL; cur = cur->next){
break;
}
if(cur == NULL){
return;
}
cur->next = pos->next;
DestoryNode(pos);
}
//删除一个元素值出现的所有情况
void LinkListDelAll(LinkNode** head,LinkType value){
if(head == NULL){
//非法输入
return;
}
if(head == NULL){
return;
}
LinkNode* cur = *head;
while(cur != NULL){
while(cur->data == value){
cur = cur->next;
}
*head = cur;
LinkNode* pos = *head;
cur = cur->next;
while(cur != NULL){
if(cur->data !=value){
pos->next = cur;
pos = pos->next;
}
cur = cur->next;
}
pos->next == NULL;
pos = pos->next;
DestoryNode(pos);
}
return;
}
//查找一个元素的值,返回地址
LinkNode* LinkListFind(LinkNode* head,LinkType value){
if(head == NULL){
return NULL;
}
LinkNode* cur = head;
for(;cur != NULL;cur=cur->next){
if(cur->data == value){
return cur;
}
}
return NULL;
}
实现完整代码;
LinkList.h:
#pragma once
#include<stdio.h>
typedef char LinkType; //重定义类型
typedef struct LinkNode{ //定义结构体
LinkType data; //数据域
struct LinkNode* next; //指针域
}LinkNode;
void LinkListInit(LinkNode** head); //初始化链表
void PrintChar(LinkNode* head,char* msg); //打印链表
void DestoryNode(LinkNode* node); //实现销毁一个结点
void LinkListDestory(LinkNode** head); //实现删除一个结点
LinkNode* CrearNewNode(LinkType value); //创建一个新结点
void LinkListPushBack(LinkNode** head,LinkType value); //尾插一个元素到链表中
void LinkListPosBack(LinkNode** head); //尾删一个元素
void LinkListPushHead(LinkNode** head,LinkType value); //头插一个元素
void LinkListPopHead(LinkNode** head); //头删一个元素
LinkNode* LinkListFind(LinkNode* head,LinkType value); //查找元素值的下标
void LinkListInsert(LinkNode* pos,LinkType value); //在Pos下标后插入值
void LinkedListInsertBef(LinkNode** head,LinkNode* pos,LinkType value); //在pos> 下标前插入元素
void LiskListDelVal(LinkNode** head,LinkType value); //删除指定元素
void LiskListDelAll(LinkNode** head,LinkType value); //删除所有的a元素
size_t LinkListSize(LinkNode* head); //元素个数
代码实现:LinkList.c
#include "LinkedList.h"
#include<stdlib.h>
//初始化链表
void LinkListInit(LinkNode** head){
*head = NULL;
}
//实现创建一个新的结点
LinkNode* CreatNewNode(LinkType value){
LinkNode* NewNode = (LinkNode*)malloc(sizeof(LinkNode));
NewNode->data = value;
NewNode->next = NULL;
return NewNode;
}
//打印代码函数
void PrintChar(LinkNode* head,char* msg){
if(head == NULL){
return;
}
printf("%s\n\n",msg);
while(head){
printf("[%c]",head->data);
head=head->next;
}
printf("\n\n");
}
//实现销毁一个结点
void DestoryNode(LinkNode* node){
if(node == NULL){
return;
}
free(node);
}
//实现删除节点
void LinkListDestory(LinkNode** head){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
//空结点
return;
}
LinkNode* cur = *head;
while(*head !=NULL){
cur = (*head)->next;
DestoryNode(*head);
*head = cur;
}
return;
}
//尾插一个元素到链表中
void LinkListPushBack(LinkNode** head,LinkType value){
if(head == NULL){
return;
}
if(*head == NULL){
*head = CreatNewNode(value);
return;
}
LinkNode *phead = *head;
while(phead->next){
phead = phead->next;
}
phead->next = CreatNewNode(value);
return;
}
//尾删一个元素
void LinkListPopBack(LinkNode** head){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
return;
//空链表
}
if((*head)->next == NULL){
DestoryNode(*head);
*head == NULL;
return;
}
LinkNode* pre = NULL;
LinkNode* cur = *head;
while(cur->next != NULL){
pre = cur;
cur = cur->next;
}
pre->next = NULL;
DestoryNode(cur);
return;
}
//头插一个元素
void LinkListPushHead(LinkNode** head,LinkType value){
if(head ==NULL){
return;
}
LinkNode* NewNode = CreatNewNode(value);
NewNode->next = *head;
*head = NewNode;
return;
}
//头删一个元素
void LinkListPopHead(LinkNode** head){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
//空链表
return;
}
LinkNode* cur = *head;
*head = (*head)->next;
DestoryNode(cur);
return;
}
//在下标为pos后插入值
void LinkListInsert(LinkNode* pos,LinkType value){
if(pos == NULL){
return;
}
LinkNode* NewNode = CreatNewNode(value);
NewNode->next = pos->next;
pos->next = NewNode;
return;
}
//在下标为pos前插入值
void LinkListInsertBef(LinkNode** head,LinkNode* pos,LinkType value){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
return;
//空链表
}
if(pos == NULL){
return;
}
LinkNode* NewNode = CreatNewNode(value);
NewNode->next = pos->next;
pos->next = NewNode;
NewNode->data = pos->data;
pos->data = value;
return;
}
//查找一个元素的值,返回地址
LinkNode* LinkListFind(LinkNode* head,LinkType value){
if(head == NULL){
return NULL;
}
LinkNode* cur = head;
for(;cur != NULL;cur=cur->next){
if(cur->data == value){
return cur;
}
}
return NULL;
}
//实现删除指定的元素
void LinkListDelVal(LinkNode** head,LinkType value){
if(head == NULL){
//非法输入
return;
}
if(*head == NULL){
//空指针
return;
}
LinkNode* cur = *head;
LinkNode* pos = LinkListFind(*head,value);
for(; cur != NULL; cur = cur->next){
break;
}
if(cur == NULL){
return;
}
cur->next = pos->next;
DestoryNode(pos);
}
//删除一个元素值出现的所有情况
void LinkListDelAll(LinkNode** head,LinkType value){
if(head == NULL){
//非法输入
return;
}
if(head == NULL){
return;
}
LinkNode* cur = *head;
while(cur != NULL){
while(cur->data == value){
cur = cur->next;
}
*head = cur;
LinkNode* pos = *head;
cur = cur->next;
while(cur != NULL){
if(cur->data !=value){
pos->next = cur;
pos = pos->next;
}
cur = cur->next;
}
pos->next == NULL;
pos = pos->next;
DestoryNode(pos);
}
return;
}
//实现元素个数
size_t LinkListSize(LinkNode* head){
if(head == NULL){
return 0;
}
LinkNode* pos = head;
size_t count = 0;
while(pos != NULL){
++count;
pos = pos->next;
}
return count;
}
//********************测试代码************************************//
#define FUNCTION printf("--------------------%s-------------------\n",__FUNCTION__);
//初始化
void TestInit(){
LinkNode* head;
LinkListInit(&head);
}
//测试尾插一个元素
void TestLinkListPushBack(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'c');
LinkListPushBack(&head,'d');
PrintChar(head,"****************尾插四个元素**************");
}
//测试尾删元素
void TestLinkListPopBack(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'c');
LinkListPushBack(&head,'d');
PrintChar(head,"****************尾插四个元素**************");
LinkListPopBack(&head);
PrintChar(head,"****************尾删一个元素**************");
}
//测试头插一个元素
void TestLinkListPushHead(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushHead(&head,'d');
LinkListPushHead(&head,'c');
LinkListPushHead(&head,'b');
LinkListPushHead(&head,'a');
PrintChar(head,"****************头插四个元素**************");
}
//测试头删一个元素
void TestLinkListPopHead(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushHead(&head,'d');
LinkListPushHead(&head,'c');
LinkListPushHead(&head,'b');
LinkListPushHead(&head,'a');
PrintChar(head,"****************头插四个元素**************");
LinkListPopHead(&head);
PrintChar(head,"****************头删一个元素**************");
}
//测试在pos下标后插入值
void TestLinkListInsert(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushHead(&head,'d');
LinkListPushHead(&head,'c');
LinkListPushHead(&head,'b');
LinkListPushHead(&head,'a');
PrintChar(head,"****************头插四个元素**************");
LinkNode* pos = head->next;
LinkListInsert(pos,'d');
PrintChar(head,"************插入一个元素******************");
}
//测试查找一个元素
void TestLinkListFind(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'c');
LinkListPushBack(&head,'d');
PrintChar(head,"****************尾插四个元素**************");
LinkNode* pos = LinkListFind(head,'a');
printf("pos except %p,actual %p\n",head->next,pos);
PrintChar(head,"****************查找元素**************");
}
//测试在pos下标前插入一个元素
void TestLinkListInsertBef(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'c');
LinkListPushBack(&head,'d');
PrintChar(head,"****************尾插四个元素**************");
LinkNode* pos = LinkListFind(head,'d');
LinkListInsertBef(&head,pos,'x');
PrintChar(head,"********************在d之前插入**********");
}
//测试在pos下标前插入一个元素
void TestLinkListDelVal(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'c');
LinkListPushBack(&head,'d');
PrintChar(head,"****************尾插四个元素**************");
LinkListDelVal(&head,'b');
PrintChar(head,"****************删除元素c*****************");
}
//测试删除所有的a元素
void TestLinkListDelAll(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'c');
LinkListPushBack(&head,'c');
PrintChar(head,"****************尾插七个元素**************");
LinkListDelAll(&head,'a');
PrintChar(head,"****************删除所有的a元素**************");
}
//测试代码
void TestSize(){
LinkNode* head;
FUNCTION;
LinkListInit(&head);
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'a');
LinkListPushBack(&head,'b');
LinkListPushBack(&head,'c');
LinkListPushBack(&head,'c');
size_t ret = LinkListSize(head);
printf("szie = %d\n",ret);
}
//主函数
int main(){
TestInit();
TestLinkListPushBack();
TestLinkListPopBack();
TestLinkListPushHead();
TestLinkListPopHead();
TestLinkListInsert();
TestLinkListFind();
TestLinkListInsertBef();
TestLinkListDelVal();
TestLinkListDelAll();
TestSize();
return 0;
}
运行部分截图: