Skip to content

C 语言实现

c
#include <stdio.h>
#include <stdlib.h>

typedef int tElem;
typedef struct Node {
    tElem data;             // 数据域
    int index;              // 索引
    struct Node * prev;     // 前缀节点指针
    struct Node * next;     // 后缀节点指针
} Node,*pNode;


/*
 * 初始化
 * 步骤:
 *  为链表头结点申请空间
 *  头结点的前缀、后缀节点指针均指向 NULL
 *  头结点的索引值为 0
 *  返回链表
*/
pNode InitList(pNode list)
{
    list = (pNode) malloc(sizeof(Node));
    list->prev = NULL;
    list->next = NULL;
    list->index = 0;
    return list;
}


/*
 * 获取链表长度
 * 步骤:
 *  定义临时变量 item ,存放链表
 *  遍历链表,当 item.next == NULL 时,此时的 item 指的是链表的最后一个节点。
 *  最后一个节点的索引值就是链表的长度,返回长度。
*/
int ListEmpty(pNode list)
{
    pNode item = list;
    while (item->next != NULL)
    {
        item = item->next;
    }
    return item->index;
}


/*
 * 打印链表
 * 步骤:
 *  遍历链表,逐一输出。
*/
void ListTraverse(pNode list)
{
    pNode item = list->next;
    int count = 0;
    while (item != NULL)
    {
        count++;
        printf("链表的第 %d 个元素是 %d\n",count,item->data);
        item = item->next;
    }
}


/*
 * 插入元素
 * 步骤:
 *  获取链表长度
 *  为新元素开一个空间存入变量 temp
 *  temp 的数据域为元素 e
 *  temp 的索引为当前长度 + 1
 *  item 的后缀节点指针指向 NULL
 *  遍历链表找到最后一个元素
 *  令最后一个元素的后缀节点指针指向 temp
 *  令 item 的前缀指针节点指向最后一个元素
 *  返回链表
*/
pNode ListInsert(pNode list,tElem e)
{
    int len = ListEmpty(list);
    pNode temp = (pNode) malloc(sizeof(Node));
    temp->data = e;
    temp->index = ++len;
    temp->next = NULL;

    pNode item = list;
    while (item->next != NULL)
    {
        item = item->next;
    }
    item->next = temp;
    temp->prev = item;

    return list;
}


/*
 * 判断元素 e 是否在链表中
*/
int ListIsIn(pNode list,tElem e)
{
    pNode item = list->next;
    while (item != NULL)
    {
        if(item->data == e)
        {
            return item->index;
        }
        item = item->next;
    }
    return 0;
}


/*
 * 获取元素 e 的前后节点元素
*/
void getElem(pNode list,tElem e)
{
    int index = ListIsIn(list,e);
    int len = ListEmpty(list);
    if(index == 1 && len == 1)
    {
        printf("元素 %d 是链表的唯一元素,无前后节点。\n",e);
        return;
    }

    if(index)
    {
        pNode item = list->next;
        while (item != NULL)
        {
            if(item->data == e)
            {
                pNode prev = item->prev;
                pNode next = item->next;

                if(index == 1 && len > 1)
                {
                    printf("元素 %d 是链表的第一个元素,无前节点,后节点元素为 %d\n",e,next->data);
                    return;
                }
                if(index == len)
                {
                    printf("元素 %d 是链表的最后一个元素,无后节点,前节点元素为 %d\n",e,prev->data);
                    return;
                }
                printf("元素 %d 的前节点元素是:%d,后节点元素是:%d\n",e,prev->data,next->data);
            }
            item = item->next;
        }
    }
    else
    {
        printf("元素 %d 不在链表中!\n",e);
    }

}


/*
 * 删除元素 e
*/
pNode ListDelete(pNode list,tElem e)
{
    int index = ListIsIn(list,e);
    int len = ListEmpty(list);
    if(index)
    {
        pNode item = list->next;
        while (item != NULL)
        {
            if(item->data == e)
            {
                if(index == len)
                {
                    item->prev->next = NULL;
                }
                else
                {
                    item->prev->next = item->next;
                    item->next->prev = item->prev;
                }
            }
            item = item->next;
        }
    }
    else
    {
        printf("元素 %d 不在链表中!\n",e);
    }
}


/*
 * 清空链表
*/
pNode ClearList(pNode list)
{
    list->prev = NULL;
    list->next = NULL;
    return list;
}


/*
 * 销毁链表
*/
pNode DestroyList(pNode list)
{
    free(list);
    return list;
}

int main() {
    pNode list = NULL;

    // 初始化
    list = InitList(list);
    printf("初始化后,链表的长度为:%d\n\n",ListEmpty(list));

    // 插入
    list = ListInsert(list,10);
    list = ListInsert(list,20);
    list = ListInsert(list,30);
    list = ListInsert(list,40);

    // 打印链表
    ListTraverse(list);
    printf("\n");

    // 获取元素 e 的前后节点元素
    getElem(list,10);
    getElem(list,20);
    getElem(list,40);
    getElem(list,50);
    printf("\n");

    // 删除元素 e
    ListDelete(list,40);
    ListTraverse(list);
    printf("\n");

    list = ClearList(list);
    printf("清空链表后,链表的长度为:%d\n",ListEmpty(list));

    list = DestroyList(list);

    return 0;
}

Java 实现

java
package Linear;

public class Demo03 {
    public static void main(String[] args) {
        DoubleChain head = new DoubleChain();
        head.HeadInsert(20);
        head.HeadInsert(10);
        System.out.println("头插元素后:");
        head.printList();
        head.TailInsert(30);
        head.TailInsert(40);
        System.out.println("尾插元素后:");
        head.printList();
        head.SeekAdjoinElem(10);
        head.SeekAdjoinElem(40);
        head.DelItem(30);
        head.ClearList();
        System.out.println("销毁线性表后:");
        head.printList();
    }
}

class DoubleChain {
    int val;
    DoubleChain prev;
    DoubleChain next;

    // 构造函数
    public DoubleChain() {}
    public DoubleChain(int val, DoubleChain prev) {
        this.val = val;
        this.prev = prev;
    }
    public DoubleChain(int val, DoubleChain prev, DoubleChain next) {
        this.val = val;
        this.prev = prev;
        this.next = next;
    }

    // 头插元素
    public void HeadInsert(int e) {
        DoubleChain temp = new DoubleChain(e,this,this.next);
        this.next = temp;
        if (temp.next != null) temp.next.prev = temp;
    }

    // 尾插元素
    public void TailInsert(int e) {
        DoubleChain item = this;
        while (item.next != null) {
            item = item.next;
        }
        item.next = new DoubleChain(e,item);
    }

    // 打印线性表
    public void printList() {
        DoubleChain item = this.next;
        if (item == null) {
            System.out.println("------ 线性表为空 ------");
            return;
        }
        int count = 0;
        while (item != null) {
            System.out.printf("\t线性表的第 %d 个元素是 %d\n",count,item.val);
            count++;
            item = item.next;
        }
    }

    // 返回元素所在节点
    public DoubleChain WhetherExist(int e) {
        DoubleChain item = this.next;
        while (item != null) {
            if(item.val == e) break;
            item = item.next;
        }
        return item;
    }

    // 查找相邻元素
    public void SeekAdjoinElem(int e) {
        DoubleChain item = this.WhetherExist(e);
        if(item == null) System.out.printf("元素 %d 不在线性表中\n",e);
        else {
            if (item.prev == this) {
                System.out.printf("元素 %d 是线性表的第一个元素,无前一个元素\n",e);
            } else System.out.printf("元素 %d 前一个元素是 %d\n",e,item.prev.val);
            if (item.next == null) {
                System.out.printf("元素 %d 是线性表的最后一个元素,无后一个元素\n",e);
            } else System.out.printf("元素 %d 后一个元素是 %d\n",e,item.next.val);
        }
    }

    // 删除元素
    public void DelItem(int e) {
        DoubleChain item = this.WhetherExist(e);
        if(item == null) System.out.printf("元素 %d 不在线性表中\n",e);
        else {
            item.prev.next = item.next;
            item.next.prev = item.prev;
            System.out.println("删除元素后:");
            this.printList();
        }
    }

    // 销毁线性表
    public void ClearList() {
        this.next = null;
        this.prev = null;
    }
}

JavaScript 实现

javascript
// 结构体的构造函数
function ListNode(val, prev, next) {
    this.val = val || 0;
    this.prev = prev || null;
    this.next = next || null;
}

// 线性表变量(头节点)
let head;

/**
 * @description: 头插入法
 * @param {*} e 元素
 */
const HeadInsert = (e) => {
    let temp = new ListNode(e, head, head.next);
    head.next = temp;
    temp.next ? temp.next.prev = temp : '';
}

/**
 * @description: 尾插入法
 * @param {*} e 元素
 */
const TailInsert = (e) => {
    let temp = new ListNode(e);
    let item = head;
    while (item.next) item = item.next;
    item.next = temp;
    temp.prev = item;
}

/**
 * @description: 遍历线性表
 */
const ErgodicList = () => {
    let count = 0;
    let item = head.next;
    while (item) {
        count++;
        console.log(`\t线性表的第 ${count} 个元素是 ${item.val}`);
        item = item.next;
    }
}

/**
 * @description: 判断元素是否在线性表中
 * @param {*} e 元素
 * @return {*} 状态 0-不存在,1-存在
 */
const WhetherExist = (e) => {
    let index = 0;
    let item = head.next;
    while (item) {
        if (item.val === e) {
            index = 1;
            break;
        }
        item = item.next;
    }
    return index;
}

/**
 * @description: 查找前后元素
 * @param {*} e 元素
 */
const SeekAdjoinElem = (e) => {
    if (WhetherExist(e)) {
        let item = head.next;
        while (item) {
            if (item.val === e) break;
            item = item.next;
        }
        if (item.prev === head) console.log(`元素 ${e} 是线性表第一个元素,无前一个元素`);
        else console.log(`元素 ${e} 的前一个元素是 ${item.prev.val}`);
        if (!item.next) console.log(`元素 ${e} 是线性表最后一个元素,无后一个元素`);
        else console.log(`元素 ${e} 的后一个元素是 ${item.next.val}`);
    } else console.log(`元素 ${e} 不在线性表中`);
}

/**
 * @description: 删除元素 e
 * @param {*} e 元素
 */
const DelItem = (e) => {
    if (WhetherExist(e)) {
        let item = head;
        while (item) {
            if (item.val === e) break;
            item = item.next;
        }
        item.prev.next = item.next;
        item.next.prev = item.prev;
        return 1;
    } else {
        console.log(`元素 ${e} 不在线性表中`);
        return;
    }
}

/**
 * @description: 清空线性表
 */
const ClearList = () => {
    head.next = null;
    head.prev = null;
}

const main = () => {
    head = new ListNode();
    HeadInsert(20);
    HeadInsert(10);
    console.log("头插入元素后:", head);

    TailInsert(30);
    TailInsert(40);
    console.log("尾插入元素后:", head);

    console.log("打印线性表:");
    ErgodicList();

    let eItem = 20;
    SeekAdjoinElem(eItem);

    console.log(`删除元素 ${eItem} 后:`);
    DelItem(eItem) ? ErgodicList() : '';

    // ClearList();
    // console.log("清空元素后:",head);

}

main();

基于 MIT 许可发布