数据结构与算法之双链表的操作

简介: 双链表的操作

链表的操作

/*
实现双链表的构建、初始化、数据添加(在指定位置添加)、数据删除(删除指定元素,并返回该元素的位置)的算法设计;
*/
#include<iostream>
#include<Windows.h>
using namespace std;
typedef struct _DoubleLink {
  int data;
  struct _DoubleLink *pre;  //指向上一节点的指针域
  struct _DoubleLink *next; //指向下一节点的指针域
}DbLinkList, DbLinkNode;
//初始化双链表
bool InitList(DbLinkList* &l) {
  l = new DbLinkList;
  if (!l) return false;
  l->pre = NULL;
  l->next = NULL;
  return true;
}
//前插法添加双向链表元素
bool addLinkFront(DbLinkList* &l, DbLinkNode* s) {
  if (!l || !s) return false;
  if (l->next==NULL) {  //只有头结点
    l->next = s;
    s->pre = l;
    s->next = NULL;
  } else {
    s->next = l->next;
    l->next->pre = s;
    l->next = s;
    s->pre = l;
  }
  return true;
}
//尾插法添加双向链表元素
bool (addLinkLasr(DbLinkList* &l,DbLinkNode* s)) {
  if (!l || !s) return false;
  DbLinkList *last = l;
  while (last->next) last = last->next; //差找到尾结点;
  s->next = NULL;
  last->next = s;
  s->pre = last;
  return true;
}
//打印输出双向链表
void PrintLinkst(DbLinkList* & l) {
  if (!l) return ;
  DbLinkList *p = l;
  while (p->next) {
    cout << p->next->data << " ";
    p = p->next;
  }
  return;
}
//在双向链表中插入指定元素
bool insert(DbLinkList* & l, int i, int x) {
  if (!l) return false;
  DbLinkList *p, *q;
  p = l;
  q = new DbLinkList;
  q->data = x;
  int index = 0;
  while (p->next) {
    if (index < i) {  //找到要插入节点的前一个节点
      index++;
      p = p->next;
    } else {
      p->next->pre = q;
      q->next = p->next;
      p->next = q;
      q->pre = p;
      return true;
    }
  }
  return false;
}
//在双向链表中删除指定元素
bool DeleteList(DbLinkList* &l, int Element, int &index) {
  if (!l||!l->next) return false;
  DbLinkList *p = l;
  while (p->next&&p->next->next) {
    if (p->next->data==Element) {
      p = p->next;
      p->pre->next = p->next;
      p->next->pre = p->pre;
      delete p;
      return true;
    }else{
      p = p->next;
      index++;
    }
  }
  if (p->next->data == Element) {
    p->next = NULL;
    return true;
  }
  return false;
}
int main(void) {
  DbLinkList *l = NULL;
  DbLinkNode *s = NULL;
  if (InitList(l)) {
    cout << "双向链表初始化成功! " << endl;
  } else {
    cout << "双向链表初始化失败! " << endl;
  }
  int chose;  //由用户选择是用前插法还是尾插法插入数据!
  //由用户选择是用前插法还是尾插法
  cout << "请选择使用前插法插入数据还是使用尾插法插入数据!" << endl;
  cout << "若要使用前插法插入数据请输入: 1" << endl;
  cout << "若要使用尾插法插入数据请输入: 2" << endl;
  cin >> chose;
  cout << "请输入要插入的元素个数: " << endl;
  int num = 0;  //用户要插入的元素个数
  cin >> num;
  //由用户选择何种方插入元素
  switch (chose) {
  case 1:
    while (num > 0) {
      cout << "请输入你想要插入的元素的值: ";
      s = new DbLinkNode;
      cin >> s->data;
      //单链表的数据添加 之 前插法
      if (addLinkFront(l, s)) {
        cout << "前插入元素!" << s->data << "成功! " << endl;
      } else {
        cout << "前插入元素失败! " << endl;
      }
      num--;
    }
    break;
  case 2:
    while (num > 0) {
      cout << "请输入你想要插入的元素的值: ";
      s = new DbLinkNode;
      cin >> s->data;
      //单链表的数据添加 之 尾插法
      if (addLinkLasr(l, s)) {
        cout << "尾插入元素!" << s->data << "成功! " << endl;
      } else {
        cout << "尾插入元素失败! " << endl;
      }
      num--;
    }
    break;
  default:
    cout << "输入不合法!!!!, 请重新输入" << endl;
    while (1) {
      cout << "请选择使用前插法插入数据还是使用尾插法插入数据!" << endl;
      cout << "若要使用前插法插入数据请输入: 1" << endl;
      cout << "若要使用尾插法插入数据请输入: 2" << endl;
      cin >> chose;
      if (chose == 1 || chose == 2) 
        break;
    }
    break;
  }
  PrintLinkst(l);
  int i;  //  插入的位置
  int x;//插入的值
  cout << "请输入你想要插入的位置: ";
  cin >> i;
  cout << "请输入你想要插入的元素: ";
  cin >> x;
  //实现双链表的构建、数据添加、数据删除的算法设计;
  if (insert(l, i, x)) {
    cout << "双向链表插入数据 : " << x << "成功,在双向链表的位置是: " << i << endl;
  } else {
    cout << "双向链表插入元素失败! " << endl;
  }
  PrintLinkst(l);
// 实现双链表的构建、数据添加、数据删除的算法设计;
  int Element;  //要删除的元素
  int index = 0;  //要删除的元素的位置
  cout << "请输入要删除的元素的值: ";
  cin >> Element;
  if (DeleteList(l, Element, index)) {
    cout << "双向链表删除数据 : " << Element << "成功,在双向链表的位置是: " << index << endl;
  } else {
    cout << "双向链表删除元素失败! " << endl;
  }
  PrintLinkst(l);
  system("pause");
  return 0;
}

前插法:

20191012004417432.png

尾插法:

       20191012004446640.png                        

目录
相关文章
|
1月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
62 4
|
2月前
|
算法 索引
❤️算法笔记❤️-(每日一刷-141、环形链表)
❤️算法笔记❤️-(每日一刷-141、环形链表)
53 0
|
2月前
|
算法
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
54 0
|
3天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
1月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
55 5
|
1月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
101 4
|
1月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
1月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
50 0
|
2月前
|
存储 缓存 算法
经典算法之链表篇(三)
经典算法之链表篇(三)