栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++实现单链表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++实现单链表

C++实现单链表
  • 一、单链表实现
  • 二、测试代码

一、单链表实现

单链表结构:数据域+指针域
单链表操作:1.创建单链表 2.遍历单链表 3.获取单链表的长度 4.判断单链表是否为空 5.获取节点 6.在尾部插入指定元素 7.在指定位置插入指定元素 8.在头部插入指定元素 9.在尾部删除元素 10.删除所有元素 11.删除指定元素 12.在头部删除元素 13.遍历反转链表 14.递归反转链表 0.退出
list.h

using DataType = int;

struct Node {
  DataType val;   // 数据域
  Node *next;     // 指针域
};

class LinkList {
 private:
  Node *head;
 public:
  LinkList();
  ~LinkList();
  void CreatLinkList(int n);
  void TraceLinkList();
  int GetLength();
  bool IsEmpty();
  Node* Find(DataType val);
  void InsertElemAtIndex(DataType val, int n);
  void InsertElemAtHead(DataType val);
  void InsertElemAtEnd(DataType val);
  void DeleteElemAtHead();
  void DeleteElemAtEnd();
  void DeleteAll();
  void DeleteElemVal(DataType val);
  void ReverseLinkList();
  Node* RecReverseLinkList(Node *head);
  void RecReverseLinkListFun();
};

list.cc

#include "./list.h"
#include 

// @description: 创建单链表
LinkList::LinkList() {
  head = new Node();
  head->val = 0;
  head->next = nullptr;
}

// @description: 销毁单链表
LinkList::~LinkList() {
  delete head;
}

// @description: 创建n个结点的单链表
void LinkList::CreatLinkList(int n) {
  Node *pnew, *ptemp;
  ptemp = head;
  if (n < 0) {
    std::cout << "input linklist size is error" << std::endl;
    return;
  }
  for (int i = 0; i < n; i++) {
    pnew = new Node();
    pnew->val = static_cast(i);
    pnew->next = nullptr;
    ptemp->next = pnew;  // 增加新节点
    ptemp = pnew;        // 节点后移一位
  }
}

// @description: 遍历链表
void LinkList::TraceLinkList() {
  if (head == nullptr || head->next == nullptr) {
    std::cout << "linklist is null" << std::endl;
  }
  Node *temp = head;
  int index = 0;
  while (temp->next != nullptr) {
    temp = temp->next;
    std::cout << "linklist index is " << index++;
    std::cout << ", linklist val is " << temp->val << std::endl;
  }
}

// @description: 获取链表长度
int LinkList::GetLength() {
  int count = 0;
  Node *node = head->next;
  while(node != nullptr) {
    ++count;
    node = node->next;
  }
  return count;
}

// @description: 判断链表是否为空
bool LinkList::IsEmpty() {
  if (head->next == nullptr) {
    return true;
  }
  return false;
}

// @description: 查找指定数据的地址
Node *LinkList::Find(DataType data) {
  Node *node = head;
  if (node == nullptr) {
    std::cout << "find link list is nullptr" << std::endl;
    return nullptr;
  } else {
    while(node->next != nullptr) {
      if (node->val == data) {
        return node;
      }
      node = node->next;
    }
    return nullptr;
  }
}

// @description: 尾部插入指定数据
void LinkList::InsertElemAtEnd(DataType data) {
  Node *new_node = new Node();  // 新增的结点
  new_node->val = data;
  new_node->next = nullptr;
  Node *temp = head;
  if (head == nullptr) {
    head = new_node;
  } else {
    while (temp->next != nullptr) {
      temp = temp->next;
    }
    temp->next = new_node;  // 新增结点加入尾部
  }
}


// @description: 指定位置插入数据
void LinkList::InsertElemAtIndex(DataType data, int n) {
  if (n < 1 || GetLength() < n) {
    std::cout << "input value error" << std::endl;
  } else {
    Node *node = new Node();
    node->val = data;
    int count = 1;
    Node *temp = head;
    while (count < n) {  // 遍历n
      temp = temp->next;
      count++;
    }
    node->next = temp->next;
    temp->next = node;
  }
}

// @description: 头部插入指定数据
void LinkList::InsertElemAtHead(DataType data) {
  Node *new_node = new Node();
  new_node->val = data;
  Node *temp = head;   // 防止修改head指向
  if (head == nullptr) {
    head = new_node;
  }
  new_node->next = temp->next;
  temp->next = new_node;
}

// @description: 删除尾部元素
void LinkList::DeleteElemAtEnd() {
  Node *node = head;
  Node *temp = nullptr;
  if (node->next == nullptr) {
    std::cout << "link list is nullptr" << std::endl;
  } else {
    while (node->next != nullptr) {
      temp = node;
      node = node->next;
    }
    delete node;
    node = nullptr;
    temp->next = nullptr;
  }
}

// @description: 删除全部元素
void LinkList::DeleteAll() {
  Node *node = head->next;
  Node *temp = new Node();
  while (node != nullptr) {
    temp = node;
    node = node->next;
    head->next = node;
    temp->next = nullptr;
    delete temp;
  }
  head->next = nullptr;
}

// @description: 删除指定数据
void LinkList::DeleteElemVal(DataType data) {
  Node *temp = Find(data);
  if (temp == head->next) {
    DeleteElemAtHead();
  } else {
    Node *node = head;
    while(node->next != temp) {
      node = node->next;
    }
    node->next = temp->next;
    delete temp;
    temp = nullptr;
  }
}

// @description: 删除头部元素
void LinkList::DeleteElemAtHead() {
  Node *node = head;
  if (node == nullptr || node->next == nullptr) {
    std::cout << "link list is nullptr" << std::endl;
  } else {
    Node *temp = nullptr;
    node = node->next;
    temp = node->next;
    delete node;
    node = nullptr;
    head->next = temp;
  }
}

// @description: 遍历链表
void LinkList::ReverseLinkList() {
  // 1->2->3->4->5
  // 5->4->3->2->1
  // https://leetcode-cn.com/problems/reverse-linked-list/
  Node *node = head;
  if (node == nullptr || head->next == nullptr) {
    std::cout << "link list is nullptr" << std::endl;
    return;
  }
  node = node->next;
  Node *temp = nullptr;  // 临时保存的指针
  Node *new_list = temp;  // 保存已经反转之后的链表,最终需要返回的指针
  while (node != nullptr) {  // 循环遍历每一个变量
    temp = node;   // 指向当前需要反转的结点1
    node = node->next;   // 当前结点指向下一个结点2
    
    temp->next = new_list;   // 切断当前结点和后面结点之间的联系,指向已经反转之后的结点
    new_list = temp;   // 保存已经反转之后的指针
  }
  head->next = new_list;
}

// @description: 递归遍历链表
Node* LinkList::RecReverseLinkList(Node *head) {
  if (head == nullptr || head->next == nullptr) {
    return head;
  }
  Node *new_head = RecReverseLinkList(head->next);  // 递归
  head->next->next = head;  // 改变head->next的指向
  head->next = nullptr;  // head->next赋值为nullptr
  return new_head;
}

void LinkList::RecReverseLinkListFun() {
  head->next = RecReverseLinkList(head->next);
}
二、测试代码

test.cc

#include "./list.h"
#include 

void LinkListPrint() {
  std::cout << "1.创建单链表   2.遍历单链表   3.获取单链表的长度   4.判断单链表是否为空   5.获取节点n";
  std::cout << "6.在尾部插入指定元素   7.在指定位置插入指定元素   8.在头部插入指定元素n";
  std::cout << "9.在尾部删除元素   10.删除所有元素   11.删除指定元素   12.在头部删除元素n";
  std::cout << "13.遍历反转链表   14.递归反转链表   0.退出" << std::endl;
}

void LinkListTest() {
  LinkList list;
  int index;
  do {
    (void)LinkListPrint();
    std::cout << "input index to execute" << std::endl;
    std::cin >> index;
    switch (index) {
    case 1:
      int length;
      std::cout << "input link list length" << std::endl;
      std::cin >> length;
      list.CreatLinkList(length);
      break;
    case 2:
      list.TraceLinkList();
      break;
    case 3:
      std::cout << "link list length is " << list.GetLength() << std::endl;
      break;
    case 4:
      if (list.IsEmpty() == true) {
        std::cout << "link list is empty" << std::endl;
      } else {
        std::cout << "link list is not empty" << std::endl;
      }
      break;
    case 5:
      DataType data;
      std::cout << "input data you want get" << std::endl;
      std::cin >> data;
      std::cout << "the data val is " << list.Find(data)->val << std::endl;
      break;
    case 6:
      DataType end_data;
      std::cout << "add data in the end of link list" << std::endl;
      std::cin >> end_data;
      list.InsertElemAtEnd(end_data);
      break;
    case 7:
      DataType index_data;
      int i;
      std::cout << "input data" << std::endl;
      std::cin >> index_data;
      std::cout << "input index" << std::endl;
      std::cin >> i;
      list.InsertElemAtIndex(index_data, i);
      break;
    case 8:
      DataType head_data;
      std::cout << "inset data at head" << std::endl;
      std::cin >> head_data;
      list.InsertElemAtHead(head_data);
      break;
    case 9:
      list.DeleteElemAtEnd();
      break;
    case 10:
      list.DeleteAll();
      break;
    case 11:
      DataType delete_data;
      std::cout << "input data you want to delete" << std::endl;
      std::cin >> delete_data;
      list.DeleteElemVal(delete_data);
      break;
    case 12:
      list.DeleteElemAtHead();
      break;
    case 13:
      list.ReverseLinkList();
      break;
    case 14:
      list.RecReverseLinkListFun();
    default:
      break;
    }
  } while (index != 0);
}

void TestReverseLinkList() {
  LinkList list;
  std::cout << "before reserse link list" << std::endl;
  list.CreatLinkList(10);
  list.TraceLinkList();
  std::cout << "after reserse link list" << std::endl;
  list.ReverseLinkList();
  list.TraceLinkList();
}

int main() {
  std::cout << "hello lch !!!" << std::endl;
  (void)LinkListTest();
  (void)TestReverseLinkList();
  std::cout << "end lch !!!" << std::endl;
  return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982463.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号