python算法与数据结构之单链表的实现代码


Posted in Python onJune 27, 2019

=一、链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。

二、单链表介绍

单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成: 元素(数据元素的映象) + 指针(指示后继元素存储位置) ,元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。它的每个节点包含两个域, 一个信息域(元素域)和一个链接域 。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。

链式存储结构的线性表将采用一组任意的存储单元存放线性表中的数据元素。由于不需要按顺序存储,链表在插入、删除数据元素时比顺序存储要快,但是在查找一个节点时则要比顺序存储要慢,使用链式存储可以克服顺序线性表需要预先知道数据大小的缺点,链表结构可以充分利用内存空间,实现灵活的内存动态管理。但是链式存储失去了数组随机存取的特点,同时增加了节点的指针域,空间开销较大。

三、单链表结构

python算法与数据结构之单链表的实现代码

  • 表元素域elem用来存放具体的数据。
  • 链接域next用来存放下一个节点的位置(python中的标识)
  • 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。

四、单链表的常用操作图解

1、头插

python算法与数据结构之单链表的实现代码

2、尾插

python算法与数据结构之单链表的实现代码

3、指定为之插入

python算法与数据结构之单链表的实现代码

4、删除

python算法与数据结构之单链表的实现代码

五、单链表的python代码实现

# 创建节点
class Node(object):
  def __init__(self,item):
    self.element = item
    self.next = None
# 创建单链表类
class SingleLinkList(object):
  def __init__(self):
    self.header = None
    self.length = 0
  # 1、判断是否为空
  def is_empty(self):
    if self.header == None:
      return True
    else:
      return False
  # 2、头部插入
  def add(self,node):
    if self.is_empty():
      self.header = node
    else:
      node.next = self.header
      self.header = node
      # currentNode = self.header
    self.length += 1
  # 3、尾部插入
  def appent(self,node):
    currentNode = self.header
    if self.is_empty():
      self.add(node)
    else:
      while (currentNode.next != None):
        currentNode = currentNode.next
      currentNode.next = node
      self.length += 1
  # 4、指定位置插入
  def insert(self,node,index):
    currentNode = self.header
    if index>self.length+1 or index<=0:
      print("你要插入的位置不对,请重现选择位置")
    if index == 1:
      self.add(node)
    elif index == 2:
      node.next = self.header.next
      self.header.next = node
      self.length += 1
    else:
      for i in range(1,index-1):
        currentNode = currentNode.next
      node.next = currentNode.next
      currentNode.next = node
      self.length += 1
  # 5、遍历
  def travel(self):
    currentNode = self.header
    if self.length == 0:
      print("你要遍历的链表没有数据\n")
    else:
      print("你要遍历的链表里面的元素有:",end=" ")
      for i in range(self.length):
        print("%s "%currentNode.element,end=" ")
        currentNode = currentNode.next
      print("\n")
  # 6、排序不用交换节点的位置,只需要交换节点上的数据值
  def list_sort(self):
    for i in range(0,self.length-1):
      currentNode = self.header
      for j in range(0,self.length-i-1):
        if currentNode.element > currentNode.next.element:
          temp = currentNode.element
          currentNode.element = currentNode.next.element
          currentNode.next.element = temp
        currentNode = currentNode.next
  # 7、按索引删除
  def remove(self,index):
    if index<=0 or index>self.length:
      print("你输入的下标不对,请重新输入")
      return
    else:
      if index == 1:
        self.header = self.header.next
        currentNode = self.header
      elif index == 2:
        currentNode = self.header
        currentNode.next = currentNode.next.next
      else:
        currentNode = self.header
        for i in range(1,index-1):
          currentNode = currentNode.next
        currentNode.next = currentNode.next.next
    self.length -= 1
  # 8、查找是否包含,并返回下标
  def isContain(self,num):
    contain = 0
    currentNode = self.header
    for i in range(self.length):
      if currentNode.element == num:
        print("%d在链表中%d处\n"%(num,i))
        contain = 1
      currentNode = currentNode.next
    if contain == 0:
      print("%d不在链表中\n"%num)
  # 9、根据下标找节点
  def searchNodeByIndex(self,index):
    currentNode = self.header
    if index<=0 or index>self.length:
      print("你输入的下标不对,请重新输入\n")
      return 0
    else:
      for i in range(index-1):
        currentNode = currentNode.next
      return currentNode
  # 10、根据下标修改节点的值
  def modifyByIndex(self,index,num):
    currentNode = self.header
    if index<=0 or index>self.length:
      print("你输入的下标不对,请重新输入\n")
    else:
      for i in range(index-1):
        currentNode = currentNode.next
      currentNode.element = num
def main():
  # 创建一个节点对象
  node1 = Node(1)
  # 创建一个单链表对象
  single_link_list = SingleLinkList()
  print("验证空链表的遍历")
  single_link_list.travel()
  print("验证头插")
  single_link_list.add(node1)
  single_link_list.travel()
  print("验证尾插")
  node2 = Node(2)
  single_link_list.appent(node2)
  single_link_list.travel()
  print("验证按位置插入")
  node3 = Node(3)
  single_link_list.insert(node3,1)
  single_link_list.travel()
  print("继续验证头插")
  node4 = Node(5)
  single_link_list.add(node4)
  single_link_list.travel()
  print("继续验证按位置插入")
  node5 = Node(4)
  single_link_list.insert(node5,4)
  single_link_list.travel()
  print("验证删除")
  single_link_list.remove(3)
  single_link_list.travel()
  print("验证查找一个节点是否在链表中")
  single_link_list.isContain(8)
  print("验证按下标查找节点")
  node = single_link_list.searchNodeByIndex(2)
  print("第二个节点的值为:%s"%node.element)
  print("\n验证排序")
  single_link_list.list_sort()
  single_link_list.travel()
  print("验证修改")
  single_link_list.modifyByIndex(2,10)
  single_link_list.travel()
if __name__ == '__main__':
  main()

运行结果为:

验证空链表的遍历
你要遍历的链表没有数据

验证头插
你要遍历的链表里面的元素有: 1 

验证尾插
你要遍历的链表里面的元素有: 1  2 

验证按位置插入
你要遍历的链表里面的元素有: 3  1  2 

继续验证头插
你要遍历的链表里面的元素有: 5  3  1  2 

继续验证按位置插入
你要遍历的链表里面的元素有: 5  3  1  4  2 

验证删除
你要遍历的链表里面的元素有: 5  3  4  2 

验证查找一个节点是否在链表中
8不在链表中

验证按下标查找节点
第二个节点的值为:3

验证排序
你要遍历的链表里面的元素有: 2  3  4  5 

验证修改
你要遍历的链表里面的元素有: 2  10  4  5 

六、单链表的C语言代码实现

#include <stdio.h>
typedef struct N
{
  int element;
  struct N *next;
}Node;
// 1、创建节点
Node *createNode(int num)
{
  Node *node;
  node = (Node *)malloc(sizeof(Node));
  node->element = num;
  node->next = NULL;
  return node;
}
// 2、创建链表
Node *createSingleLinkList(Node *node)
{
  Node *head = node;
  return head;
}
// 3、获取链表长度
int getlength(Node *head)
{
  if (head == NULL)
  {
    return 0;
  }
  int count = 1;
  Node *current = head;
  while (current->next != NULL)
  {
    count++;
    current = current->next;
  }
  return count;
}
// 4、头部插入
Node * add(Node *head, Node *node)
{
  if(head == NULL)
  {
    head = node;
    return head;
  }
  else
  {
    node->next = head;
    head = node;
    return head;
  }
}
// 5、尾部插入
Node * append(Node *head,Node *node)
{
  Node *current = head;
  if (current->next == NULL)
  {
    add(head, node);
  }
  else
  {
    int len = getlength(head);
    for (int i = 0; i<len-1; i++)
    {
      current = current->next;
    }
    current->next = node;
  }
  return head;
}
// 6、按下标插入节点
Node * insert(Node *head,Node *node,int index)
{
  int len = getlength(head);
  if (index<=0||index>len+1)
  {
    printf("你要插入的位置不对,请重现选择位置");
  }
  Node *current = head;
  if (index == 1)
  {
    head = add(head, node);
  }
  else if (index == 2)
  {
    node->next = head->next;
    head->next = node;
  }
  else
  {
    for (int i = 1; i<index-1; i++)
    {
      current = current->next;
    }
    node->next = current->next;
    current->next = node;
  }
  return head;
}
// 7、遍历
void travel(Node *head)
{
  int len = getlength(head);
  printf("len = %d\n",len);
  Node *current = head;
  if (len == 0)
  {
    printf("你要遍历的链表没有数据\n");
  }
  else
  {
    printf("你要遍历的链表里面的元素有: ");
    for (int i = 0; i<len; i++)
    {
      printf("%d ",current->element);
      current = current->next;
    }
    printf("\n");
  }
}
// 8、根据索引删除
Node * delect(Node *head,int index)
{
  int len = getlength(head);
  if (index<=0||index>len)
  {
    printf("你输入的下标不对,请重新输入");
    return head;
  }
  else
  {
    if (index == 1)
    {
      head = head->next;
    }
    else if (index == 2)
    {
      head->next = head->next->next;
    }
    else
    {
      Node *current = head;
      for (int i = 1; i<index-1; i++)
      {
        current = current->next;
      }
      current->next = current->next->next;
    }
  }
  return head;
}
// 9、查找是否包含,并返回下标
void isContain(Node *head,int num)
{
  int contain = 0;
  Node *current = head;
  int len = getlength(head);
  for (int i = 0; i<len; i++)
  {
    if (current->element == num)
    {
      printf("%d在链表中的%d处\n",num,i+1);
      contain = 1;
    }
    current = current->next;
  }
  if (contain == 0)
  {
     printf("%d不在链表中\n",num);
  }
}
// 10、根据下标找节点
Node *searchByIndex(Node *head , int index)
{
  int len = getlength(head);
  Node *current = head;
  if (index<=0||index>len)
  {
    printf("你输入的下标不对,请重新输入");
    return head;
  }
  else
  {
    for (int i = 0; i<index-1; i++)
    {
      current = current->next;
    }
    return current;
  }
}
// 11、根据下标修改节点的值
void modifyByIndex(Node *head,int index,int num)
{
  int len = getlength(head);
  Node *current = head;
  if (index<=0||index>len)
  {
    printf("你输入的下标不对,请重新输入");
  }
  else
  {
    for (int i = 0; i<index-1; i++)
    {
      current = current->next;
    }
    current->element = num;
  }
}
int main(int argc, const char * argv[])
{
  printf("==========1、创建节点==========\n");
  Node * node1 = createNode(1);
  printf("==========2、创建单链表==========\n");
  Node * head = createSingleLinkList(node1);
  travel(head);
  printf("==========3、验证头插==========\n");
  Node *node2 = createNode(0);
  head = add(head, node2);
  travel(head);
  Node *node3 = createNode(2);
  head = add(head, node3);
  travel(head);
  printf("==========4、验证尾插==========\n");
  Node *node4 = createNode(4);
  head = append(head,node4);
  travel(head);
  Node *node5 = createNode(5);
  head = append(head,node5);
  travel(head);
  printf("==========5、验证按下标插入==========\n");
  Node *node6 = createNode(6);
  head = insert(head, node6, 1);
  travel(head);
  printf("==========6、验证按下标删除==========\n");
  head = delect(head, 2);
  travel(head);
  printf("==========7、验证是否包含==========\n");
  isContain(head, 8);
  printf("==========8、验证根据下标找节点==========\n");
  Node *n = searchByIndex(head, 1);
  printf("第一个节点是%d\n",n->element);
  printf("==========9、验证根据下标修改==========\n");
  modifyByIndex
(head, 3, 9);
    travel(head);
    return 0;
}

运行结果为:

==========1、创建节点==========
==========2、创建单链表==========
len = 1
你要遍历的链表里面的元素有: 1
==========3、验证头插==========
len = 2
你要遍历的链表里面的元素有: 0 1
len = 3
你要遍历的链表里面的元素有: 2 0 1
==========4、验证尾插==========
len = 4
你要遍历的链表里面的元素有: 2 0 1 4
len = 5
你要遍历的链表里面的元素有: 2 0 1 4 5
==========5、验证按下标插入==========
len = 6
你要遍历的链表里面的元素有: 6 2 0 1 4 5
==========6、验证按下标删除==========
len = 5
你要遍历的链表里面的元素有: 6 0 1 4 5
==========7、验证是否包含==========
8不在链表中
==========8、验证根据下标找节点==========
第一个节点是6
==========9、验证根据下标修改==========
len = 5
你要遍历的链表里面的元素有: 6 0 9 4 5

总结

以上所述是小编给大家介绍的python算法与数据结构之单链表的实现代码 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python实现k均值算法示例(k均值聚类算法)
Mar 16 Python
Python爬取京东的商品分类与链接
Aug 26 Python
python实现多线程抓取知乎用户
Dec 12 Python
python利用拉链法实现字典方法示例
Mar 25 Python
Python字符串处理实例详解
May 18 Python
简单了解OpenCV是个什么东西
Nov 10 Python
基于python 二维数组及画图的实例详解
Apr 03 Python
numpy的文件存储.npy .npz 文件详解
Jul 09 Python
python使用folium库绘制地图点击框
Sep 21 Python
django中间键重定向实例方法
Nov 10 Python
Python numpy数组转置与轴变换
Nov 15 Python
浅谈pytorch 模型 .pt, .pth, .pkl的区别及模型保存方式
May 25 Python
python多线程并发实例及其优化
Jun 27 #Python
int在python中的含义以及用法
Jun 27 #Python
Pycharm运行加载文本出现错误的解决方法
Jun 27 #Python
基于python-opencv3的图像显示和保存操作
Jun 27 #Python
pycharm new project变成灰色的解决方法
Jun 27 #Python
python之mock模块基本使用方法详解
Jun 27 #Python
python文件选择对话框的操作方法
Jun 27 #Python
You might like
php图片的裁剪与缩放生成符合需求的缩略图
2013/01/11 PHP
CI框架简单邮件发送类实例
2016/05/18 PHP
jQuery 学习入门篇附实例代码
2010/03/16 Javascript
js面向对象 多种创建对象方法小结
2012/05/21 Javascript
js 表单提交后按钮变灰的实例代码
2013/08/16 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
AngularJs expression详解及简单示例
2016/09/01 Javascript
详解vue mint-ui源码解析之loadmore组件
2017/10/11 Javascript
vuejs实现递归树型菜单组件
2018/01/13 Javascript
浅析Vue中method与computed的区别
2018/03/06 Javascript
微信小程序中实现手指缩放图片的示例代码
2018/03/13 Javascript
解决vue router组件状态刷新消失的问题
2018/08/01 Javascript
vue组件(全局,局部,动态加载组件)
2018/09/02 Javascript
Typescript的三种运行方式(小结)
2019/09/18 Javascript
Python实现的检测web服务器健康状况的小程序
2014/09/17 Python
Python 错误和异常代码详解
2018/01/29 Python
详解10个可以快速用Python进行数据分析的小技巧
2019/06/24 Python
python中while和for的区别总结
2019/06/28 Python
Jupyter Notebook远程登录及密码设置操作
2020/04/10 Python
Python发送邮件封装实现过程详解
2020/05/09 Python
Python爬虫实现百度翻译功能过程详解
2020/05/29 Python
Python将字典转换为XML的方法
2020/08/01 Python
CSS实现雨滴动画效果的实例代码
2019/10/08 HTML / CSS
新加坡最受追捧的体验平台:Hapz
2018/01/01 全球购物
植村秀美国官网:Shu Uemura美国
2019/03/19 全球购物
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
工程预算与管理应届生求职信
2013/10/06 职场文书
超级搞笑检讨书
2014/01/15 职场文书
三年级音乐教学反思
2014/01/28 职场文书
房务中心文员岗位职责
2014/04/16 职场文书
商场促销活动策划方案
2014/08/18 职场文书
学生夜不归宿检讨书
2014/09/23 职场文书
2015年母亲节活动策划方案
2015/05/04 职场文书
简单聊聊Vue中的计算属性和属性侦听
2021/10/05 Vue.js