单链表基本操作实现

来源:互联网 发布:ubuntu安装硬盘分区 编辑:程序博客网 时间:2024/06/05 18:59

单链表:链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。用图表示如下:


其中0,1,2,3分别是四个独立的节点,每个节点都是由本身的元素和指向下一个元素地址的指针构成的结构体。每个节点在初始化的时候都将指向下一个节点的指针初始为NULL,所以到最后一个节点时,他的指向下一个节点的指针就为NULL,这个节点也就是尾节点。

请注意:头结点和第一结点是两个结点,百度百科解释为:为方便操作,在单链表的第一个结点之前附设一个结点,称之为头结点。接下来贴上一些关于链表的基本操作完成:

(编译环境:VS2015)

list.h(函数声明以及结构体定义)

#pragma once#include <stdio.h>#include <assert.h>#include <Windows.h>#include <malloc.h>typedef int DataType;typedef struct ListNode{DataType data;struct ListNode* next;}ListNode;ListNode* Buycode(DataType x); //创建结点void PrintList(ListNode* pList); //打印链表void PushBack(ListNode** ppList, DataType x); //再最后的位置插入一个节点void PopBack(ListNode** ppList); //删除最后一个节点void PushFront(ListNode** ppList, DataType x); //在最前面插入一个节点void PopFront(ListNode** ppList); // 删除最前面的节点ListNode* Find(ListNode* pList, DataType x); //查找一个节点void Insert(ListNode** ppList, ListNode* pos, DataType x); // 在pos的前面插入一个节点xvoid Erase(ListNode** ppList, ListNode* pos); // 删除Pos节点

list.c(函数实现)

#define _CRT_SECURE_NO_WARNINGS 1#include "List.h"ListNode* Buycode(DataType x) //每次开辟一个节点并初始化赋值{ListNode* Node = (ListNode*)malloc(sizeof(ListNode));Node->data = x;Node->next = NULL;return Node;}void PrintList(ListNode* pList){ListNode* cur = pList;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");}void PushBack(ListNode** ppList, DataType x){//空链表if (NULL == *ppList){*ppList = Buycode(x);}//有一个头结点else if (NULL == (*ppList)->next){(*ppList)->next = Buycode(x);}//多个else{ListNode* tmp = *ppList;while (tmp->next){tmp = tmp->next;}tmp->next = Buycode(x);}}void PopBack(ListNode** pplist)//尾删{//1.空//2.只有一个节点//3.多个节点if (*pplist == NULL){return;}else if ((*pplist)->next == NULL){free(*pplist);*pplist = NULL;}else{ListNode* cur = *pplist;ListNode* pos = cur;while (cur->next){pos = cur;//pos和cur指向同一个节点cur = cur->next;//pos指向cur前一个节点}free(cur);cur = NULL;pos->next = NULL;}}void PushFront(ListNode** ppList, DataType x){//空的情况if (*ppList == NULL){*ppList = Buycode(x);}else{ListNode* tmp = Buycode(x);tmp->next = *ppList;*ppList = tmp;}}void PopFront(ListNode** ppList){if (*ppList == NULL){return;}else{ListNode* tmp = (*ppList)->next;free(*ppList);*ppList = tmp;}}ListNode* Find(ListNode* pList, DataType x) {while (pList){if (pList->data == x){return pList;}pList = pList->next;}return NULL;}void Insert(ListNode** ppList, ListNode* pos, DataType x){assert(pos);//1.空链表//2.只有一个头结点//3.要插入位置的为头结点//4.多个节点if ((*ppList == NULL) || ((*ppList)->next == NULL) || (pos == *ppList)){PushFront(ppList,x);}else{ListNode* tmp = NULL;ListNode* cur = *ppList;while (cur->next != pos){cur = cur->next;}tmp = Buycode(x);cur->next = tmp;tmp->next = pos;}}void Erase(ListNode** ppList, ListNode* pos){assert(*ppList);//1为空2只有一个if ((*ppList == NULL) || ((*ppList)->next == NULL) || (*ppList == pos)){PopFront(ppList);}//多个节点else{ListNode* tmp = *ppList;while (tmp->next != pos){tmp = tmp->next;}tmp->next = pos->next;free(pos);pos = NULL;}}

test.c(测试函数)

#define _CRT_SECURE_NO_WARNINGS 1#include "List.h"void Test3(){ListNode* list = NULL;PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);ListNode* pos = Find(list, 2);Insert(&list, pos, 4);PrintList(list);pos = Find(list, 2);Erase(&list, pos);PrintList(list);}//PushFront,PopFrontvoid Test2(){ListNode* list = NULL;PushFront(&list, 1);PushFront(&list, 2);PushFront(&list, 3);PushFront(&list, 4);PrintList(list);PopFront(&list);PrintList(list);PopFront(&list);PrintList(list);PopFront(&list);PrintList(list);PopFront(&list);PrintList(list);PopFront(&list);PrintList(list);}//PushBack,PopBackvoid Test1(){ListNode* list = NULL;PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PrintList(list);PopBack(&list);PrintList(list);PopBack(&list);PrintList(list);PopBack(&list);PrintList(list);PopBack(&list);PrintList(list);PopBack(&list);PrintList(list);}int main(){Test3();//Test2();//Test1();system("pause");return 0;}

如有错误,请及时与我联系谢谢~




原创粉丝点击