c++实现单链表

来源:互联网 发布:黑客帝国之矩阵革命 编辑:程序博客网 时间:2024/06/06 02:59
链表概念:链表是一种线性表,但不是顺序存储,而是每个节点里面存储着下一个节点的指针,把存储数据的元素串联起来。链表又有单链表、双向链表、循环链表这几种常见的形式。
接线来我们就来简单实现以下单链表的一些简单操作。

#pragma once
#include <assert.h>
typedef int Datatype;   //数据类型为int
typedef struct Node
{
   Data type data;        //数据data
   struct Node* next;   //指向下一个的指针*next
}Node;

//增删查改的实现
void PrintList(Node* pHead)   //pHead为头结点,打印链表的元素
void PushBack(Node** ppHead,DataType x)  //尾插,使用二级指针存储指向头结点的指针的地址,以便于找到头结点
void PopBack(Node** ppHead) //尾删
void PushFront(Node** ppHead, DataType x)  //头插
void PopFront(Node** ppHead)  //头删

//在pos前面进行
void Insert(Node** ppHead,Node* pos,Datatype x);  //在pos位置的前面插入数据
void Erase(Node** ppHead,Node* pos);  //删除
void Find(Node* pHead,Datatype x);  //查找元素
void SortList(Node* pHead);  //排序


Node* BuyNode(Datatype x);//链表的创建
{
   Node* node = (Node*)malloc(sizeof(Node));//动态开辟空间存储链表的数据
   node->data = x;
   node->next = NULL;

   return node;
}

void PushBack(Node** ppHead,DataType x)
{
   if(*ppHead == NULL) //没有结点
   {
    *ppHead = BuyNode(x);
   }
    else
   {
   Node* tail = *ppHead;//将头结点当做尾节点,即只有一个结点时
   while(tail->next)//当尾节点的next不等于空,继续循环的执行
   {
   tail = tail->next;
   }
   tail->next = BuyNode(x);
   }
}

void PrintList(Node* pHead)
{
   Node* cur = pHead;//记录头结点
   while(cur)//cur指向的位置不是空时,继续循环
   {
   printf("%d",cur->data);
   cur = cur->next;
   }
   printf("/n");
}

void PopBack(Node** ppHead)//尾删
{
   if(*ppHead == NULL)//没有节点
   {
    return;
   }

else if((*ppHead)->next == NULL)//一个结点
   {
     free(*ppHead);
     *ppHead = NULL;
   }
else 
   {
   Node* cur = *ppHead;//cur指向头结点,从头开始
   Node* prev = NULL;//prev指针置空
   while(cur->next)//cur->next不为空时,继续循环
   {
     prev = cur;//用prev记录cur,记录的是尾节点的前一个节点
     cur = cur->next;//后移一步
   }
     prev->next = NULL;//将prev的下一个位置置空
     free(cur);//释放掉cur指向的节点的空间,就将尾节点删除了
   }
}

void PushFront(Node** ppHead,DataType x)//头插
{
  /* if(*ppHead == NULL)//头为空
   {
     *ppHead = BuyNode(x);//创建一个头结点
   }
else
   {
     Node* tmp = BuyNode(x);//创建一个结点,用临时指针tmp指向这个创建的结点
     tmp->next = *ppHead;//tmp的next指向头结点
    *ppHead = tmp;//再把新创建的这个节点作为头结点
   }*/
   Node* tmp = BuyNode(x);
   tmp->next = *ppHead;
   *ppHead = tmp;
}

void PopBack(Node** ppHead)//头删
{
   if(*ppHead == NULL)//头为空
   {
     return;
   }
else if((*ppHead)->next ==NULL)//只有一个结点
{
   free(*ppHead);//释放这个头结点
   *ppHead == NULL;//将头结点的指针置空
}
else
{
   Node* next = (*ppHead)->next;//用*next记录头结点的下一个位置
   free(*ppHead);//释放掉头结点
   *ppHead = next;//在把之前头结点的下一个位置的结点作为头结点
}
}


void Insert(Node** ppHead,Node* pos,DataType x)//在pos位置的前面插入数据
{
   assert(pos);//防御式编程,防止在一个空位置插入数据
   if(pos = *ppHead)//只有一个 头结点
   {
     PushFront(ppHead,x);//直接调用头插进行插入
   }
   else
   {
     Node* tmp = BuyNode(x);//创建一个 临时指针*tmp指向要插入的新节点
     Node* prev = *ppHead;//用*prev指向头结点
     while(prev->next != pos)//使用循环使*prev向后挪动到pos的前一个位置
   {
     prev = prev->next;
   }
   prev->next = tmp;//将pos前一个位置的结点的next指向要插入的结点
   tmp->next = pos;//将要插入的结点的next指向pos,这样就完成了在pos位置的前面进行插入数据
   }
}

void Erase(Node** ppHead,Node* pos)//删除pos位置的数据
{
   assert(pos);
   if(pos == ppHead)//如果删除的位置是头结点的位置
   {
     PopFront(ppHead);//头删
   }
   else if(pos->next == NULL)//一个结点
   {
     PopBack(ppHead);//尾删
   }
   else
   {
     Node* prev = *ppHead, *next = pos->next;//用*prev指向头结点,*next指向pos的下一个位置
     while(prev->next != pos)//利用循环将prev挪动到pos的前一个位置
   {
     prev = prev->next;//向前挪动数据
   }
   prev->next = next;//将prev的next指向pos的下一个位置的结点
   free(pos);//释放掉pos位置,就将pos位置删除
   }
}

Node* Find(Node* pHead,DataType x)//查找某个元素
   {
     Node* cur = pHead;//从cur位置开始
     while(cur)//cur不为空,循环继续
   {
     if(cur->data == x)//找到,则返回cur指向的结点的数据
   {
     return cur;
   }
     cur = cur->next;//cur向后挪动
   }
   return NULL://没找到,则返回NULL
   }





以上就是单链表的简单操作的实现。