C/C++,数据结构单链表(采用C++"引用"方法)(寻找节点、在某处插入结点、删除某位置结点)


C++中的引用方法


引用――定义别名,

int count1 = 0;
int &count2 = count1;//用在变量定义

void Swap(int&a, int&b)//用在函数形式参数定义
{
 int tmp = a;
 a = b;
 b = tmp;
}


从下文的例子中可以看出采用“引用”方法在函数实现的时候更加方便简单

void PushBack(SListNode **ppHead, DataType x)
{
 assert(ppHead);
 if (*ppHead == NULL)
 {
  *ppHead = _BuyNode(x);
 }
 else
 {
  SListNode *tail = *ppHead;
  while (tail!=NULL)
  {
   tail = tail->next;
  }
  tail = _BuyNode(x);
 }
}

void PushBack(SListNode* &pHead, DataType x)//使用引用 定义别名的方法实现尾插
{
 //不需断言
 if (pHead == NULL)
 {
  pHead = _BuyNode(x);
 }
 else
 {
  SListNode *tail = pHead;
  while (tail->next != NULL)
  {
   tail = tail->next;
  }
  tail->next = _BuyNode(x);
 }
}


//**********SListNode.h****************
#pragma once

#ifndef __SLISTNODE_H__
#define __SLISTNODE_H__

//--------添加头文件-----------
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//--------链表结构------------

typedef int DateType;  //定义数据类型为 int

typedef int DataType;

typedef struct SListNode
{
 DataType data;
 struct SListNode *next;
}SListNode;


//--------函数-------------
void PrintNode(SListNode *&pHead);//打印链表
void PushBack(SListNode* &pHead, DataType x);//使用引用 定义别名的方法实现尾插
void PushBack_p(SListNode **ppHead, DataType x);
void PopBack(SListNode* &pHead);//尾删
void PushFront(SListNode* &pHead, const DataType x);//头插
void PopFront(SListNode* &pHead);//头删
SListNode* Find(SListNode* pHead, const DataType x);//寻找data为x的结点
void Insert(SListNode* pos, const DataType x);//在pos处插入新结点
void Erase(SListNode*&pHead,SListNode* pos);//删除pos位置的结点(删除pos前的节点,删除pos位置结点更好的方法在下一篇博客论述)


#endif   //__SLISTNODE_H__


//***********SListNode.cpp****函数实现*******

#include"SListNode.h"

SListNode *_BuyNode(DataType x)//开辟新结点
{
 SListNode *tmp = (SListNode *)malloc(sizeof(SListNode));
 tmp->data = x;
 tmp->next = NULL;
 return tmp;
}

void PushBack_p(SListNode **ppHead, DataType x)
{
 assert(ppHead);
 if (*ppHead == NULL)
 {
  *ppHead = _BuyNode(x);
 }
 else
 {
  SListNode *tail = *ppHead;
  while (tail!=NULL)
  {
   tail = tail->next;
  }
  tail = _BuyNode(x);
 }
}

void PushBack(SListNode* &pHead, DataType x)//使用引用 定义别名的方法实现尾插
{
 //不需断言
 if (pHead == NULL)
 {
  pHead = _BuyNode(x);
 }
 else
 {
  SListNode *tail = pHead;
  while (tail->next != NULL)
  {
   tail = tail->next;
  }
  tail->next = _BuyNode(x);
 }
}

void PopBack(SListNode* &pHead)//尾删 
{
 //不需断言
 //注意 空、一个节点 、多个节点三种情况
 if (pHead == NULL)
 {
  printf("SListNode is NULL\n");
  return;
 }
 if (pHead->next == NULL)
 {
  free(pHead);
  pHead = NULL;
 }
 else
 {
  SListNode *tail = pHead;
  while (tail->next->next != NULL)
  {
   tail = tail->next;
  }
  free(tail->next);
  tail->next = NULL;
 }
}

void PushFront(SListNode* &pHead, const DataType x)//头插
{
 //无需断言
 if (pHead == NULL)
 {
  pHead = _BuyNode(x);
 }
 else
 {
  SListNode *tmp = _BuyNode(x);
  tmp->next = pHead;  //针对没有头结点的情况
  pHead = tmp;
 }
}

void PopFront(SListNode* &pHead)//头删
{
 //不需断言
 //注意 空、多个节点三种情况
 if (pHead == NULL)
 {
  printf("SListNode is NULL\n");
  return;
 }
 else
 {
  SListNode *head = pHead->next;
  free(pHead);
  pHead = head;
 }
}

SListNode* Find(SListNode* pHead, const DataType x)
{
 assert(pHead);
 SListNode*tmp = pHead;
 while (tmp != NULL)
 {
  if (tmp->data == x)
   return tmp;
  tmp = tmp->next;
 }
 printf("%d 不在此链表中\n", x);
 return NULL;
 }

void Insert(SListNode* pos, const DataType x)//在pos后插入新结点
{
 if (pos == NULL)
 {
  pos = _BuyNode(x);
 }
 else
 {
  SListNode* tmp = _BuyNode(x);
  tmp->next = pos->next;
  pos->next = tmp;
 }
}

void Erase(SListNode*&pHead, SListNode* pos)//删除pos位置后面的一个元素
{
 //考虑 空、 首元结点、 非首元结点、 不存在pos位置
 assert(pHead);
 assert(pos);
 if (pHead == pos)
 {
  pHead = pHead->next;
  free(pos);
 }
 SListNode* prev = pHead;
 while (prev)
 {
  if (prev->next == pos)
  {
   prev->next = pos->next;
   free(pos);
   pos = NULL;
   break;
  }
  prev = prev->next;
 }
 return;
}

void PrintNode(SListNode *&pHead)
{
 SListNode *tmp = pHead;
 while (tmp)
 {
  printf("%d->", tmp->data);
  tmp = tmp->next;
 }
 printf("NULL\n");
}

//***********test.cpp****************
#define _CRT_SECURE_NO_WARNINGS

#include"SListNode.h"

void Test1()  //PushBack\PopBack
{
 printf("//Test1() PushFront/PopFront\n");
 SListNode *LL = NULL;
 PushBack(LL, 1);
 PushBack(LL, 2);
 PushBack(LL, 3);
 PushBack(LL, 4);
 PrintNode(LL);

 PopBack(LL);
 PrintNode(LL);
 PopBack(LL);
 PrintNode(LL);
 PopBack(LL);
 PrintNode(LL);
 PopBack(LL);
 PrintNode(LL);
 PopBack(LL);
 PrintNode(LL);
}
void Test2()//PushFront\PopFront
{
 printf("//Test2() PushFront/PopFront\n");
 SListNode *LL = NULL;
 PushFront(LL, 1);
 PushFront(LL, 2);
 PushFront(LL, 3);
 PushFront(LL, 4);
 PrintNode(LL);

 PopFront(LL);
 PrintNode(LL);
 PopFront(LL);
 PrintNode(LL);
 PopFront(LL);
 PrintNode(LL);
 PopFront(LL);
 PrintNode(LL);
 PopFront(LL);
 PrintNode(LL);
}
void Test3()
{
 printf("//Test3() Insert/Erase \n");
 SListNode *LL = NULL;
 PushBack(LL, 1);
 PushBack(LL, 2);
 PushBack(LL, 4);
 PushBack(LL, 5);
 PrintNode(LL);
 Insert(LL, 0);
 PrintNode(LL);
 Insert(Find(LL, 5), 6);
 PrintNode(LL);
 Insert(Find(LL, 2), 3);
 PrintNode(LL);

 Erase(LL, Find(LL, 6));
 PrintNode(LL);
 Erase(LL, Find(LL, 0));
 PrintNode(LL);
 Erase(LL, Find(LL, 1));
 PrintNode(LL);
 Erase(LL, Find(LL, 5));
 PrintNode(LL);
 Erase(LL, Find(LL, 2));
 PrintNode(LL);
 Erase(LL, Find(LL, 4));
 PrintNode(LL);
 Erase(LL, Find(LL, 6));//当出现链表中不存在的元素Fine函数会返回NULL,
 //Erase函数第二个参数为NULL,断言assert检测到会返回错误
 PrintNode(LL);
 Erase(LL, Find(LL, 3));
 PrintNode(LL);
 free(LL);
}
int main()
{
 //Test1();
 //Test2();
 Test3();
 system("pause");
 return 0;
}

wKiom1aHZLPTzUM_AAAkLdZGpvA720.png

wKiom1aHZLOj3Z8aAAAhSjYVp74667.png


在Erase(LL, Find(LL, 6));处插入断点

wKiom1aHZLSBAqMjAAAopL4Zg3c189.png

wKioL1aHZNbDKpdyAACDaRdOuZg467.png


你可能感兴趣的:(数据结构,c/c++,单链表)