python算法与数据结构-双向链表(40)
程序员文章站
2023-08-12 12:10:26
一、双向链表的介绍 一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。 上图是双向链表的结构图,即通过上一个节点可以找到下一个,通过下一个也可以找到上一个节点。 二、双向 ......
一、双向链表的介绍
一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
上图是双向链表的结构图,即通过上一个节点可以找到下一个,通过下一个也可以找到上一个节点。
二、双向链表插入和删除的图解
1、插入图解
2、删除图解
三、双向链表的python代码实现
# 1、创建节点 class node(object): # 初始化方法 def __init__(self, item): self.item= item self.next = none self.prev = none # 2、创建循环链表 class doublelinklist(object): # 初始化方法 def __init__(self): self._head = none # 3、判断是否为空 def is_empty(self): """判断链表是否为空""" return self._head == none # 4、求其长度 def length(self): """返回链表的长度""" cur = self._head count = 0 while cur != none: count += 1 cur = cur.next return count # 遍历 def travel(self): """遍历链表""" print("你要遍历的链表元素有:",end=" ") cur = self._head while cur != none: print("%s "%cur.item,end=" ") cur = cur.next print("") # 5、头插 def add(self, item): """头部插入元素""" node = node(item) if self.is_empty(): # 如果是空链表,将_head指向node self._head = node else: # 将node的next指向_head的头节点 node.next = self._head # 将_head的头节点的prev指向node self._head.prev = node # 将_head 指向node self._head = node # 6、尾插 def append(self, item): """尾部插入元素""" node = node(item) if self.is_empty(): # 如果是空链表,将_head指向node self._head = node else: # 移动到链表尾部 cur = self._head while cur.next != none: cur = cur.next # 将尾节点cur的next指向node cur.next = node # 将node的prev指向cur node.prev = cur # 7、查找 def search(self, item): """查找元素是否存在""" cur = self._head while cur != none: if cur.item == item: return true cur = cur.next return false # 8、指定位置插入 def insert(self, pos, item): """在指定位置添加节点""" if pos <= 0 or pos>self.length()+1 : print("你输入的位置有误,请重新输入") elif pos == 1: self.add(item) elif pos == self.length()+1: self.append(item) else: node = node(item) cur = self._head count = 1 # 移动到指定位置的前一个位置 while count < (pos - 1): count += 1 cur = cur.next # 将node的prev指向cur node.prev = cur # 将node的next指向cur的下一个节点 node.next = cur.next # 将cur的下一个节点的prev指向node cur.next.prev = node # 将cur的next指向node cur.next = node # 9、删除 def remove(self, item): """删除元素""" if self.is_empty(): return else: cur = self._head if cur.item == item: # 如果首节点的元素即是要删除的元素 if cur.next == none: # 如果链表只有这一个节点 self._head = none else: # 将第二个节点的prev设置为none cur.next.prev = none # 将_head指向第二个节点 self._head = cur.next return while cur != none: if cur.item == item: # 将cur的前一个节点的next指向cur的后一个节点 cur.prev.next = cur.next # 将cur的后一个节点的prev指向cur的前一个节点 cur.next.prev = cur.prev break cur = cur.next # 验证 if __name__ == '__main__': double_link = doublelinklist() # 头插 double_link.add(1) # 遍历 double_link.travel() # 尾插 double_link.append(2) double_link.travel() # 按照索引插入 double_link.insert(3,4) double_link.travel() double_link.insert(3,3) double_link.travel() # 删除 double_link.remove(3) double_link.travel()
运行结果为:
你要遍历的链表元素有: 1 你要遍历的链表元素有: 1 2 你要遍历的链表元素有: 1 2 4 你要遍历的链表元素有: 1 2 3 4 你要遍历的链表元素有: 1 2 4
四、双向链表的c语言代码实现
// main.m // 双向链表 // created by 侯垒 on 2019/6/28. // copyright © 2019 可爱的侯老师. all rights reserved. #import <foundation/foundation.h> typedef struct n { int element; struct n *next; struct n *prev; }node; // 创建节点 node *createnode(int num) { node *node = (node *)malloc(sizeof(node)); node->element = num; node->next = null; node->prev = null; return node; } // 创建双向链表 node *createdoublelinklist(node *node) { node *head = node; return head; } // 判断是否为空 int is_empty(node *head) { if (head == null) { return 1; } else { return 0; } } // 求其长度 int length(node *head) { node *current = head; int count = 0; while (current != null) { count++; current = current->next; } return count; } // 遍历 void travel(node *head) { printf("你要遍历的数据有:"); node *current = head; while (current != null) { printf("%d ",current->element); current = current->next; } printf("\n"); } // 头插 node * add(node *head,int num) { node *node = createnode(num); if (is_empty(head)==1) { head = node; } else { node->next = head; head->prev = node; head = node; } return head; } // 尾插 node* append(node *head,int num) { node *node = createnode(num); if (is_empty(head)==1) { head = node; } else { node *current = head; while (current->next != null) { current = current->next; } current->next = node; node->prev = current; } return head; } // 查找 int search(node *head,int num) { node *current = head; for (int i=0; i<length(head); i++) { if (current->element == num) { return i+1; } current = current->next; } return 0; } // 按指定位置插入 node * insert(node *head ,int index,int num) { if (index<=0||index>length(head)+1) { printf("你要插入的位置不对,请重新插入"); } else if (index == 1) { head = add(head, num); } else if (index == length(head)+1) { append(head, num); } else { node *node = createnode(num); node *current = head; for (int i=1; i<index-1; i++) { current = current->next; } node->prev = current; node->next = current->next; current->next->prev = node; current->next = node; } return head; } // 删除元素 node * removenode(node *head,int num) { if (is_empty(head)==1) { printf("你要删除的链表为空"); } else { node *current = head; //处理头结点就是要删除的节点 if (current->element == num) { if (current->next == null) { // 只有首节点这一个元素 head = null; } else { // 要删除的是首节点,但是后面还有元素 current->next->prev = null; head = current->next; } } else { while (current!=null) { if (current->element == num) { current->prev->next = current->next; current->next->prev = current->prev; break; } current = current->next; } } } return head; } int main(int argc, const char * argv[]) { // 创建节点 node *node = createnode(1); // 创建链表 node *head = createdoublelinklist(node); // 验证遍历 travel(head); // 验证头插 head = add(head, 0); travel(head); // 验证尾插 head = append(head, 3); travel(head); // 验证查找 int index = search(head, 1); if (index != 0) { printf("你要查找的数据在%d位置\n",index); } else { printf("没有找到你要的数据\n"); } //验证按指定位置插入 head = insert(head, 2, 2); travel(head); //验证删除 head = removenode(head, 0); travel(head); return 0; }
运行结果为:
你要遍历的数据有:1 你要遍历的数据有:0 1 你要遍历的数据有:0 1 3 你要查找的数据在2位置 你要遍历的数据有:0 2 1 3 你要遍历的数据有:2 1 3
上一篇: python随机验证码(数字和字母组合)
推荐阅读