数据结构算法——双向链表

双向链表与单链表相比,各个节点多了一个指向前一个节点的指针,即一个节点有一个指向前驱的指针和指向后继的指针。本文将主要介绍双向链表的基本操作,包括正向遍历链表,反向遍历链表,查找链表中的元素,节点的插入,节点的删除等操作。


双向链表结构

/* 双向链表节点结构 */
struct Node
{
    int data;
    Node * next, Node * pre;
    Node() { data = 0; next = nullptr; pre = nullptr; }
};

/* 定义头节点 */
Node * header = new Node;
/* 定义尾节点 */
Node * tail = new Node;
tail = header;

正向遍历链表

void TraverseLinkList(Node * header)
{
    if(!header->next)
        return;

    Node * temp = header->next;  
    while (temp) 
    {  
        cout << temp->data << " ";  
        temp = temp->next;  
    }  
    cout << endl;  
}

反向遍历链表

双向链表有尾节点,所以直接从尾节点从后向前遍历即可

void reverseLinkList(Node * tail)
{
    Node * temp = tail;  
    while (temp) 
    {  
        cout << temp->data << " ";  
        temp = temp->pre;  
    }  
    cout << endl;  
}

查找元素

Node * Findelement(Node * header, int val)
{
    if(!header->next)
        return;

    Node * temp = header->next;
    while(temp)
    {
        if(temp->data == val)
            return temp;
        temp = temp->next;
    }
    return NULL;
}

插入元素

插入元素有多种情况,首先看在链表末尾插入元素

void append(Node* tail, int val)
{
    Node* node = new Node; 
    node->data = val; 
    tail->next = node;
    node->pre = tail;
    tail = node;
}

头部插入

void pushfront(Node* header, int val)
{
    Node* node = new Node; 
    node->data = val; 
    header->next = node;
    node->pre = header;
}

其他位置插入

void insert(Node* header, int k, int val)
{
    Node* node = new Node; 
    node->data = val; 
    if(k==0)  //头部插入
    {
        pushfront(header,val);
        return;
    }

    int count = 1;
    Node* temp = header->next;
    while(temp)
    {
        if(count == k)
        {
            node->next = temp->next;
            node->pre = temp;
            temp->next->pre = node;
            temp->next = node;          
        }
        count++;
    }
}

删除元素

void erase(Node* header, int val)
{
    if(!header->next)
        return;

    Node* temp = header->next;
    while(temp)
    {
        if(val == temp->data)
        {
            Node* tpre = temp->pre;
            temp->pre->next = temp->next;
            temp->next->pre = tpre;
            delete temp;
            temp = NULL;
        }
    }
}
package 单双向链表; /** * 单向链表增删改查操作 * */ public class LinkTest { public static void main(String[] args) { Link l=new Link(); l.addNode("A"); l.addNode("B"); l.addNode("C"); l.addNode("D"); l.addNode("E"); l.printNode(); System.out.println("\n是否包含D:"+l.contains("D")); System.out.println("==========删除之前的内容=========="); l.printNode(); System.out.println("\n==========删除之后的内容=========="); l.deleteNode("A"); l.printNode(); } } class Link{//链表的完成类 class Node{//保存每个节点 private String data;//节点内容 private Node next;//下一个节点 public Node(String data){ this.data=data; } public void add(Node newNode) {//将节点加入到合适的位置 if(this.next==null){ this.next=newNode; }else{ this.next.add(newNode); } } public void print() {//输出节点的内容 System.out.print(this.data+"\t"); if(this.next!=null){ this.next.print();//递归调用输出 } } public boolean search(String data){//内部搜索的方法 if(data.equals(this.data)){ return true; }else{ if(this.next!=null){//向下继续判断 return this.next.search(data); }else{ return false; } } } public void delete(Node previous, String data) { if(data.equals(this.data)){//找到了匹配的节点 previous.next=this.next;//空出当前的节点 }else{ if(this.next!=null){ this.next.delete(this, data);//继续查找 } } } } private Node root;//链表中的根节点 public void addNode(String data){//增加节点 Node newNode=new Node(data); if(root==null){ root=newNode; }else{ root.add(newNode); } } public void printNode(){//链表的输出 if(root!=null){ root.print(); } } public boolean contains(String name){//判断元素是否存在 return this.root.search(name); } public void deleteNode(String data){//链表删除节点 if(this.contains(data)){ if(this.root.data.equals(data)){//如果是根节点 this.root=this.root.next;//修改根节点 }else{ this.root.next.delete(root,data);//把下一个节点的前节点和要删除的节点内容一起传入 } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值