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 相关文章推荐
windows下安装python的C扩展编译环境(解决Unable to find vcvarsall.bat)
Feb 21 Python
Python3处理HTTP请求的实例
May 10 Python
django一对多模型以及如何在前端实现详解
Jul 24 Python
django中使用Celery 布式任务队列过程详解
Jul 29 Python
Python中list的交、并、差集获取方法示例
Aug 01 Python
Python编写带选项的命令行程序方法
Aug 13 Python
基于python调用psutil模块过程解析
Dec 20 Python
python如何删除文件、目录
Jun 23 Python
python list等分并从等分的子集中随机选取一个数
Nov 16 Python
Python开发.exe小工具的详细步骤
Jan 27 Python
python urllib和urllib3知识点总结
Feb 08 Python
Django如何与Ajax交互
Apr 29 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
桌面中心(四)数据显示
2006/10/09 PHP
用PHP将数据导入到Foxmail的实现代码
2010/09/05 PHP
深入理解PHP之require/include顺序 推荐
2011/01/02 PHP
PHP中isset()和unset()函数的用法小结
2014/03/11 PHP
php5.2 Json不能正确处理中文、GB编码的解决方法
2014/03/28 PHP
让codeigniter与swfupload整合的最佳解决方案
2014/06/12 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
2018/01/29 PHP
Laravel框架自定义公共函数的引入操作示例
2019/04/16 PHP
JavaScript 自动完成脚本整理(33个)
2009/10/20 Javascript
提升PHP安全:8个必须修改的PHP默认配置
2014/11/17 Javascript
jQuery中:checkbox选择器用法实例
2015/01/03 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
浅谈jQuery的bind和unbind事件(绑定和解绑事件)
2017/03/02 Javascript
利用Vue2.x开发实现JSON树的方法
2018/01/04 Javascript
简单谈谈javascript高级特性
2019/09/04 Javascript
python结合opencv实现人脸检测与跟踪
2015/06/08 Python
Django中传递参数到URLconf的视图函数中的方法
2015/07/18 Python
Python简单连接MongoDB数据库的方法
2016/03/15 Python
Python中shutil模块的常用文件操作函数用法示例
2016/07/05 Python
python中利用zfill方法自动给数字前面补0
2018/04/10 Python
django的settings中设置中文支持的实现
2019/04/28 Python
Python如何在windows环境安装pip及rarfile
2020/06/15 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
利用纯CSS3实现动态的自行车特效源码
2017/01/20 HTML / CSS
在子网210.27.48.21/30种有多少个可用地址?分别是什么?
2014/07/27 面试题
车辆维修工自我评价怎么写
2013/09/20 职场文书
外国语学院毕业生自荐信
2013/10/28 职场文书
《神奇的克隆》教学反思
2014/04/10 职场文书
大学生职业生涯十年规划书范文
2014/09/17 职场文书
第二批党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
九华山导游词
2015/02/03 职场文书
2016年寒假见闻
2015/10/10 职场文书
幼儿园教师心得体会范文
2016/01/21 职场文书
Redis高并发缓存架构性能优化
2022/05/15 Redis