一、链表

  链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
  使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。

二、单链表介绍

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

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

三、单链表结构

  

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

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

  1、头插

  

  2、尾插

  

  3、指定为之插入

  

  4、删除

  

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

运行结果为:

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

写到此处以吐血,相信你看的也会吐血!!!!

python算法与数据结构-单链表(38)的更多相关文章

  1. python实现数据结构单链表

    #python实现数据结构单链表 # -*- coding: utf-8 -*- class Node(object): """节点""" ...

  2. cc150:实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针

    实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针. 样例: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不须要返回什么,得到一个新链表:a- ...

  3. Python算法与数据结构--求所有子数组的和的最大值

    Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个 ...

  4. C语言数据结构-单链表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作

    1.数据结构-单链表的实现-C语言 typedef struct LNode { int data; struct LNode* next; } LNode,*LinkList; //这两者等价.Li ...

  5. 数据结构——单链表java简易实现

    巩固数据结构 单链表java实现 单链表除了表尾 每个几点都有一个后继 结点有数据和后继指针组成  通过构建表头和表尾(尾部追加需要)两个特殊几点 实现单链表的一些操作,代码如下 package co ...

  6. 【数据结构和算法】001 单链表 LinkedList

    一.单链表(LinkedList)介绍和内存布局 链表是有序的列表,它在内存中的实际存储结构如下: 看上去虽然无序,但他是靠灭个链表节点元素的地址和next域来分清首尾相连的顺序,如下图所示,由头指针 ...

  7. C# 数据结构 - 单链表 双链表 环形链表

    链表特点(单链表 双链表) 优点:插入和删除非常快.因为单链表只需要修改Next指向的节点,双链表只需要指向Next和Prev的节点就可以完成插入和删除操作. 缺点:当需要查找某一个节点的时候就需要一 ...

  8. python算法与数据结构-算法介绍(31)

    一.算法和数据结构 什么是算法和数据结构?如果将最终写好运行的程序比作战场,我们程序员便是指挥作战的将军,而我们所写的代码便是士兵和武器. 那么数据结构和算法是什么?答曰:兵法!故,数据结构和算法是一 ...

  9. python中的数据结构-链表

    一.什么是链表 链表是由一系列节点构成,每个节点由一个值域和指针域构成,值域中存储着用户数据,指针域中存储这指向下一个节点的指针.根据结构的不同,链表可以分为单向链表.单向循环链表.双向链表.双向循环 ...

随机推荐

  1. 转载:Adb远程连接Android系统(通过网络使用ADB(Connect to android with wifi))

    本文介绍如何通过网络(尤指无线网络)与Android的adbd进行连接.原理:adb server: 计算机上的一个服务进程,进程名为adbadb daemon: Android 手机上的一个服务进程 ...

  2. HDU 4862 Jump(更多的联合培训学校1)(最小费用最大流)

    职务地址:pid=4862">HDU4862 最小费用流做的还是太少. 建图想不出来. . . 直接引用官方题解的话吧... 最小K路径覆盖的模型.用费用流或者KM算法解决,构造二部图 ...

  3. rabbitmq集群 + Mirror Queue + 使用C#

    搭建高可用的rabbitmq集群 + Mirror Queue + 使用C#驱动连接 我们知道rabbitmq是一个专业的MQ产品,而且它也是一个严格遵守AMQP协议的玩意,但是要想骚,一定需要拿出高 ...

  4. NuttX 构建系统

    (嵌入式 实时操作系统 rtos nuttx 7.1 makefile) NuttX 构建系统 转载请注明出处: http://blog.csdn.net/zhumaill/article/detai ...

  5. C++于public、protected和private说明(From MSDN)

    public(C# 參考): https://msdn.microsoft.com/zh-cn/library/yzh058ae.aspx protected(C# 參考):https://msdn. ...

  6. Win10局域网内无法共享的解决方法分享(开启Server和ComputerBrowser服务,其它文章也不错)

    局域网共享是办公环境下经常使用的,而有些用户反应在升级到win10系统后,网络总是无法共享,给用户带来了很大的困扰,如果你也遇上这样的情况,并通过一些方法无较后,不妨尝试下小编提供的方法. 如果在Wi ...

  7. 零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果

    原文:零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果 又来一篇五分钟做设计啦~ 本篇将教大家如何运用Design内建工具Blend Path ...

  8. POCO文档翻译:POCO C++库入门指南

    内容目录 介绍 Foundation库 XML库 Util库 Net库 将这些东西组合到一起 介绍 POCO C++库是一组开源C++类库的集合,它们简化及加速了用C++来开发以网络功能为核心的可移植 ...

  9. Swift 开源那点事儿

    最近各大网站上最喜大普奔的新闻莫过于 Swift 正式开源这条了.这无疑是一个里程碑式的前进,苹果也向开源社区更加进了一步.那么 Swift 开源后有什么具体的改变呢,我们一一道来. 成立开源社区 s ...

  10. wcf 代理实例

    通过过代理调用 wcf服务 using Microsoft.Extensions.Options; using System; using System.Collections.Generic; us ...