双向链表是如何构造的,元素的插入和删除是如何实现的?
1.双向链表的构造
2.双向链表元素插入
流程图
3.C语言实现
//头部插入
void insertFirst(int data) {
DoubleNode* newDoubleNode = (DoubleNode*)malloc(sizeof(DoubleNode));
newDoubleNode->data = data;
if (first == NULL) {
last = newDoubleNode;
} else {
newDoubleNode->prev = first;
}
newDoubleNode->next = first;
first = newDoubleNode;
}
//尾部插入
void insertLast(int data) {
DoubleNode* newDoubleNode = (DoubleNode*)malloc(sizeof(DoubleNode));
newDoubleNode->data = data;
if (first == NULL) {
first = newDoubleNode;
} else {
newDoubleNode->prev = last;
last->next = newDoubleNode;
}
last = newDoubleNode;
}
void insertAfter(int key, int data)
{
DoubleNode *newDoubleNode = (DoubleNode *)malloc(sizeof(DoubleNode));
newDoubleNode->data = data;
DoubleNode *current = first;
//current为null有两种情况 一种是链表为空,一种是找不到key值
if (current == NULL)
{
if (first == NULL) //1、链表为空
{
first = newDoubleNode; //则插入第一个结点(其实可以调用其它的Insert方法)
last = newDoubleNode; //first和last均指向该结点(第一个结点)
}
else //2、找不到key值,则在链表尾部插入一个新的结点
{
last->next = newDoubleNode;
newDoubleNode->prev = last;
last = newDoubleNode;
}
}
else{
if (current == last) //第三种情况,找到了key值,分两种情况
{ //1、key值与最后结点的data相等,由于newNode将是最后一个结点,则将last指向newNode
newDoubleNode->next = current->next;
last = newDoubleNode;
}
else //2、两结点中间插入
{
newDoubleNode->next = current->next;
current->next->prev = newDoubleNode;
}
current->next = newDoubleNode;
newDoubleNode->prev = current;
}
}
4.Java实现
//中间插入
public void insertAffter(int key, int data) {
DoubleLinkNode newNode = new DoubleLinkNode(data);
DoubleLinkNode current = firstNode;
while (current != null && current.getValue() != key) {
current = current.getNextNode();
}
//若当前结点current为空
if (current == null){
if (isEmpty()){
firstNode = newNode;
lastNode = newNode;
}else {
// 找不到key值,则在链表尾部插入一个新的结点
lastNode.setNextNode(newNode);
newNode.setPrevNode(lastNode);
lastNode = newNode;
}
}else {
//找到了key,但位置在最后一位
if (current == lastNode){
newNode.setNextNode(null);
lastNode = newNode;
}else {
//在两个结点间插入
newNode.setNextNode(current.getNextNode());
current.getNextNode().setPrevNode(newNode);
}
current.setNextNode(newNode);
newNode.setPrevNode(current);
}
}
// 测试方法
public static void main(String[] args) {
DoubleLinkNodeListDemo linkNodeListDemo = new DoubleLinkNodeListDemo();
linkNodeListDemo.insertFirst(20);
linkNodeListDemo.insertFirst(30);
linkNodeListDemo.insertLast(10);
linkNodeListDemo.insertAffter(30,5);
linkNodeListDemo.displayForward();
}
// 输出结果
List(first--->last): {30} {5} {20} {10}
5双链表元素删除
//删除首元素
public DoubleLinkNode deleteFirst() {
DoubleLinkNode temp = firstNode;
//若链表只有一个结点,删除后链表为空,将last指向null
if (firstNode.getNextNode() == null) {
lastNode = null;
} else {
//若链表有两个及以上的结点 ,因为是头部删除,则first.next将变成第一个结点,其previous将变成null
firstNode.getNextNode().setPrevNode(null);
}
//将first.next赋给first
firstNode = firstNode.getNextNode();
//返回删除的结点
return temp;
}
//从尾部删除结点
public DoubleLinkNode deleteLast() {
DoubleLinkNode temp = lastNode;
//如果链表只有一个结点,则删除以后为空表,last指向null
if (firstNode.getNextNode() == null) {
firstNode = null;
} else {
//将上一个结点的next域指向null
lastNode.getPrevNode().setNextNode(null);
}
//上一个结点称为最后一个结点,last指向它
lastNode = lastNode.getPrevNode();
//返回删除的结点
return temp;
}
// 从中间删除结点
public DoubleLinkNode deleteKey(int key){
DoubleLinkNode current = firstNode;
while (current != null && current.getValue() != key){
current = current.getNextNode();
}
if (current == null){
return null;
}else {
if (current == firstNode){
firstNode.getNextNode().setPrevNode(null);
firstNode = current.getNextNode();
}else if (current == lastNode){
lastNode.getPrevNode().setNextNode(null);
lastNode = current.getPrevNode();
}else {
current.getNextNode().setPrevNode(current.getPrevNode());
current.getPrevNode().setNextNode(current.getNextNode());
}
}
return current;
}