双向循环链表简单的插入、删除、修改以及查找功能的实现

本文介绍了一个双向循环链表的实现方法,并提供了多种链表操作的代码示例,包括插入、删除、更新和查询等功能。
```
#include <stdio.h>
#include <stdlib.h>

#define T 1
#define F 0

typedef int ElementType;
typedef int Boolean;
typedef struct node* Node;

struct node //定义双向的结构体
{
    struct node* prior;
    ElementType value;
    struct node* next;
};

Boolean make(Node *head);//创建一个新的结点
Boolean init(Node *head);//创建一个双向循环的结点,并使之成为头结点
Boolean insert_tail(Node head, ElementType value);//实现尾插入
Boolean insert_index(Node head, int index, ElementType value);//实现按位置插入
Boolean insert_head(Node head, ElementType value);//实现头插入
Boolean delete_index(Node head, int index);//按位置删除
Boolean delete_value(Node head, ElementType value);//按值删除
Boolean update_index(Node head, int index, ElementType value);//按位置替换
Boolean update_value(Node head, ElementType old_value, ElementType new_value);//按值替换
Boolean query_index(Node head, int index);//查找所给位置的值
Boolean query_value(Node head, ElementType value);//查找所给值的位置
int length(Node head);//计算链表长度
void print_p(Node head);//前序遍历打印
void print_n(Node head);//后序遍历打印
int main()
{
    Node head;
    make(&head);
    init(&head);

    ElementType i;
    for (i = 0; i < 10; i++) //按头插入0~9
    {
        insert_head(head, i);    
    }
    for (i = 0; i < 10; i++) //按尾插入0~9
    {
        insert_tail(head, i);    
    }

    insert_index(head, 3, 99); //在3位置插入99
    insert_index(head, 0, 99); //在0位置插入99
    insert_index(head, length(head), 99); //在链表最后位置插入99

    print_p(head); //前序遍历打印
    print_n(head);  //后序遍历打印

    delete_index(head, 4); //删除位置4
    print_p(head);
    delete_value(head, 0); //删除0值
    print_p(head);

    update_index(head, 0, 100); //将0位置的数改为100
    update_index(head, length(head) - 1, 100); //将最后一个数改为100
    print_p(head);

    update_value(head, 100, 101); //将100改为101
    print_p(head);
    print_n(head);

    query_index(head, 15); //查找第15位的值

    query_value(head, 101); //查找值为101的位置
    printf("%d\n", length(head)); //打印链表的长度
    return 0;
} 
//以下是实现各功能的调用函数的程序
Boolean query_value(Node head, ElementType value)
{
    Node temp = head;
    int index = 0;
    while (temp->next != head)
    {
        if (value == temp->next->value)
        {
            printf("%d is on %d\n", value, index);
        }
        index++;
        temp = temp->next;
    }
    return T;
}
Boolean query_index(Node head, int index)
{
    if (index < 0 || index >= length(head))
    {
        printf("out of range\n");
        return F;
    }
    int i;
    for (i = 0; i < index; i++)
    {
        head = head->next;
    }
    printf("%d is %d\n", index, head->next->value);
    return T;
}
Boolean update_value(Node head, ElementType old_value, ElementType new_value)
{
    Node temp = head;
    while (temp->next != head)
    {
        if (old_value == temp->next->value)
        {
            temp->next->value = new_value;
        }
        temp = temp->next;
    }
    return T;
}
Boolean update_index(Node head, int index, ElementType value)
{
    if (index < 0 || index >= length(head))
    {
        printf("out of range\n");
        return F;
    }
    int i;
    for (i = 0; i < index; i++)
    {    
        head = head->next;
    }    
    head->next->value = value;
    return T;
}
Boolean delete_value(Node head, ElementType value)
{
    Node temp = head;
    while (temp->next != head)
    {
        if (value == temp->next->value)
        {
            Node temp2 = temp->next;
            temp->next = temp->next->next;
            temp->next->prior = temp;
            free(temp2);
        }
        else
        {
            temp = temp->next;
        }
    }

    return T;
}
Boolean delete_index(Node head, int index)
{
    if (index < 0 || index >= length(head))
    {
        printf("out of range\n");
        return F;
    }    
    int i;
    for (i = 0; i < index; i++)
    {
        head = head->next;
    }
    Node temp = head->next;
    head->next = head->next->next;
    head->next->prior = head; 
    free(temp);
    return T;
}
int length(Node head)
{
    int count = 0;
    Node temp = head;

    while (temp->next != head)
    {
        count++;
        temp = temp->next;
    }
    return count;
    return T;
}
Boolean insert_index(Node head, int index, ElementType value)
{
    if (index < 0 || index > length(head))
    {
        printf("out of range\n");
        return F;
    }
    Node newnode;
    make(&newnode);
    newnode->value = value;

    int i;
    for (i = 0; i < index; i++)
    {
        head = head->next;
    }
    newnode->next = head->next;
    head->next = newnode;

    newnode->prior = head;
    newnode->next->prior = newnode;
    return T;    
}
Boolean insert_head(Node head, ElementType value)
{
    Node newnode;
    make(&newnode);
    newnode->value = value;

    newnode->next = head->next;
    head->next = newnode;

    newnode->prior = head;
    newnode->next->prior = newnode;
    return T;
}
void print_p(Node head)
{
    Node temp = head;
    while (temp->prior != head)
    {
        printf("%d ", temp->prior->value);
        temp = temp->prior;
    }
    printf("\n");
}
void print_n(Node head)
{
    Node temp = head;
    while (temp->next != head)
    {
        printf("%d ", temp->next->value);
        temp = temp->next;
    }
    printf("\n");
}
Boolean insert_tail(Node head, ElementType value)
{
    Node newnode;
    make(&newnode);
    newnode->value = value;

    head->prior->next = newnode;
    newnode->next = head;
    newnode->prior = head->prior;
    head->prior = newnode;
    return T;
}
Boolean init(Node *head)
{
    Node newnode;
    make(&newnode);

    newnode->next = newnode;
    newnode->prior = newnode;

    *head = newnode;
    return T;
}
Boolean make(Node *head)
{
    Node newnode = (Node)malloc(sizeof(struct node));
    if (NULL == newnode)
    {
        return F;
    }
    *head = newnode;
    return T;
}

函数在Linux下的实现

双向循环链表是一种特殊的链表结构,每个节点都有指向前一个节点和后一个节点的指针,且链表的首尾相连。以下是双向循环链表的建立、插入查找删除方法: ### 建立双向循环链表 建立双向循环链表,首先要创建一个头节点,让其 `next` 和 `prior` 指针都指向自身,形成一个循环。后续再逐个插入节点。 ```c #include <stdio.h> #include <stdlib.h> typedef int data_d; typedef struct dlinklist { data_d data; struct dlinklist *next; struct dlinklist *prior; } Dlinklist; // 创建头结点 Dlinklist *Create_Dlinklist() { Dlinklist *head = (Dlinklist *)malloc(sizeof(Dlinklist)); if (head == NULL) { printf("内存分配失败\n"); return NULL; } head->next = head; head->prior = head; return head; } ``` ### 插入操作 插入操作可分为在头部插入和按位置插入。在头部插入时,新节点的 `next` 指向原头节点的 `next`,原头节点的 `next` 的 `prior` 指向新节点,新节点的 `prior` 指向头节点,头节点的 `next` 指向新节点。按位置插入则需要先找到插入位置,再进行指针调整。 ```c // 从头结点插入新的结点 void Dlinklist_In_head(Dlinklist *head, data_d New_data) { Dlinklist *newNode = (Dlinklist *)malloc(sizeof(Dlinklist)); if (newNode == NULL) { printf("内存分配失败\n"); return; } newNode->data = New_data; newNode->next = head->next; head->next->prior = newNode; newNode->prior = head; head->next = newNode; } // 按位置插入新元素 void Dlinklist_Add_pos(Dlinklist *head, int pos, data_d New_data) { if (pos < 1) { printf("位置不合法\n"); return; } Dlinklist *newNode = (Dlinklist *)malloc(sizeof(Dlinklist)); if (newNode == NULL) { printf("内存分配失败\n"); return; } newNode->data = New_data; Dlinklist *p = head; int i = 0; while (p->next != head && i < pos - 1) { p = p->next; i++; } if (i < pos - 1) { printf("位置超出链表长度\n"); free(newNode); return; } newNode->next = p->next; p->next->prior = newNode; newNode->prior = p; p->next = newNode; } ``` ### 查找操作 查找操作是遍历链表,比较每个节点的数据与要查找的数据是否相等,若相等则返回该节点指针,若遍历完都未找到则返回 `NULL`。 ```c // 查找元素 Dlinklist *Dlinklist_Find(Dlinklist *head, data_d target) { Dlinklist *p = head->next; while (p != head) { if (p->data == target) { return p; } p = p->next; } return NULL; } ``` ### 删除操作 删除操作可按位置删除,先找到要删除的节点,然后调整其前后节点的指针,最后释放该节点的内存。 ```c // 按位置删除元素 void Dlinklist_Delete_pos(Dlinklist *head, int pos) { if (pos < 1) { printf("位置不合法\n"); return; } Dlinklist *p = head->next; int i = 1; while (p != head && i < pos) { p = p->next; i++; } if (p == head) { printf("位置超出链表长度\n"); return; } p->prior->next = p->next; p->next->prior = p->prior; free(p); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值