双向链表的建立、插入、删除、

双向链表简介

  在循环链表中虽然能够实现从任一一结点出发找到其前驱,但时间复杂度是O(n),从表中希望迅速找到其前驱,可为每个结点增加一个指向其前驱的指针prior,这样链表中有两条方向不同的链,称为双向链表

typedef struct Node
{
    int data;
    struct Node *prior,*next;//prior前驱,next后继
}Node,*DoubleLinkList;

  p指向双向链表中某一结点,以下成立

p->prior->next==p;
p->next->prior==p;

  建立双向链表

void CreatDLLinkList(DoubleLinkList DL)
{
    Node *p,*s;
    p=DL;
    int x,flag=1;
    printf("Please input data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            s->prior=p;
            p=s;
        }
        else
        {
            p->next=DL;
            DL->prior=p;
            flag=0;
        }
    }
}

  双向链表的插入

  指针变化情况

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *prior,*next;//prior前驱,next后继
}Node,*DoubleLinkList;

void InitDLLinkList(DoubleLinkList *DL)
{
    *DL=(DoubleLinkList)malloc(len);
    (*DL)->next=NULL;
    (*DL)->prior=NULL;
}

void CreatDLLinkList(DoubleLinkList DL)
{
    Node *p,*s;
    p=DL;
    int x,flag=1;
    printf("Please input data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            s->prior=p;
            p=s;
        }
        else
        {
            p->next=DL;
            DL->prior=p;
            flag=0;
        }
    }
}

void InDLLinkList(DoubleLinkList DL,int i,int x)
{
    Node *p=DL->next,*s;          //p=DL->next开始,第一个结点开始
    int k=1;
    if(i<=0)
    {
        printf("You enter location illegal I is too small\n");
        return;
    }
    while(p!=DL&&k<i)            //最后一个位置也能插 ,p指向被插入的位置
    {
        p=p->next;
        k++;
    }
    if(p==DL)
    {
        printf("You enter location illegal I is too big\n");
        return;
    }
    s=(Node *)malloc(len);
    s->data=x;
    s->prior=p->prior;
    p->prior->next=s;
    s->next=p;
    p->prior=s;
}

void PrintDLLinkList(DoubleLinkList DL)
{
    Node *p;
    p=DL->next;
    for(;p!=DL;p=p->next)
        printf("%-3d",p->data);
    printf("\n");
}

int main()
{
    DoubleLinkList DL;
    InitDLLinkList(&DL);
    CreatDLLinkList(DL);
    PrintDLLinkList(DL);

    int x,i;
    printf("Please enter the location you want to insert:\n");
    scanf("%d",&i);
    printf("Please enter the values you want to insert:\n") ;
    scanf("%d",&x);

    InDLLinkList(DL,i,x);
    PrintDLLinkList(DL);
    free(DL);
    return 0;
}

  双向链表的删除

  找到被删除的结点p后,使p的前驱的后继指向p的后继,p的后继的前驱指向p的前驱

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *prior,*next;
}Node,*DoubleLinkList;

void InitDLLinkList(DoubleLinkList *DL)
{
    *DL=(DoubleLinkList)malloc(len);
    (*DL)->next=NULL;
    (*DL)->prior=NULL;
}

void CreatDLLinkList(DoubleLinkList DL)
{
    Node *p,*s;
    p=DL;
    int x,flag=1;
    printf("Please input data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            s->prior=p;
            p=s;
        }
        else
        {
            p->next=DL;
            DL->prior=p;
            flag=0;
        }
    }
}

void DelDLLinkList(DoubleLinkList DL,int i)
{
    Node *p=DL->next;          //从第一个数据节点开始,不是头结点
    int k=1;
    if(i<=0)
    {
        printf("You enter location illegal:\n");
        return;
    }
    while(p!=DL&&k<i)            //p指向被删除的结点
    {
        p=p->next;
        k++;
    }
    p->prior->next=p->next;      //p的前驱的后继指向p的后继
    p->next->prior=p->prior;     //p的后继的前驱指向p的前驱
    free(p);
}

void PrintDLLinkList(DoubleLinkList DL)
{
    Node *p;
    p=DL->next;                    //
    for(;p!=DL;p=p->next)          //
        printf("%-3d",p->data);
    printf("\n");
}

int main()
{
    int i;
    DoubleLinkList DL;
    InitDLLinkList(&DL);
    CreatDLLinkList(DL);
    printf("Please enter the location you want to insert:\n");
    scanf("%d",&i);
    DelDLLinkList(DL,i);
    PrintDLLinkList(DL);
    free(DL);
    return 0;
}

原文地址:https://www.cnblogs.com/tianzeng/p/9695195.html

时间: 2024-11-05 19:01:39

双向链表的建立、插入、删除、的相关文章

双向链表排序、插入删除等基本操作

未考虑性能,只是能完成基本功能,应付公司考试而已. 1 // list.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include<stdlib.h> 6 typedef struct tag_data 7 { 8 int age; 9 }Data; 10 typedef struct tag_node Node; 11 typedef struct tag_node 12 { 13 Node* pnext; 1

双向循环链表 初始化 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(DuLNode)

单链表 初始化 创建 头插法 尾插法 插入 删除 查找 合并 长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(LNode) #

Oracle序列使用:建立、删除

在开始讲解Oracle序列使用方法之前,先加一点关于Oracle client sqlplus的使用,就是如果执行多行语句的话一定要加“/”才能表示结束,并执行!本篇文章的主题是通过创建Oracle序列和触发器实现表的主键自增. 1.首先创建序列,Oracle序列的语法格式为:CREATE SEQUENCE 序列名[INCREMENT BY n][START WITH n][{MAXVALUE/ MINVALUE n|NOMAXVALUE}][{CYCLE|NOCYCLE}][{CACHE n|

[LeetCode] Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数

Design a data structure that supports all following operations in average O(1) time. insert(val): Inserts an item val to the set if not already present. remove(val): Removes an item val from the set if present. getRandom: Returns a random element fro

Sql—表格的建立,删除,数据的建立与删除-总结篇

一,Sql—表格的建立,删除,数据的建立与删除 Sql表格的建立公式 If exists (select * from sysobjects where <表名> Drop table <表名> Create table <表名> (<列名1> <数据类型> <约束类型> <是否为空>, <列名2> <数据类型> <约束类型> <是否为空>,    (约束类型如果没有可以不写

顺序表 初始化 插入 删除 查找 合并 交换 判断为空 求长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(SqList) #define MLC (Li

静态链表 初始化 定位 Malloc Free 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define MAX_SIZE 1000;//表最大空间 /* //线性表的基本操

AVL树非递归插入删除思路

AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增加和删除可能需要通过一次或多次树旋转来重新平衡这个树.AVL树得名于它的发明者G.M. Adelson-Velsky和E.M. Landis,他们在1962年的论文<An algorithm for the organization of information>中发表了它. 节点的平衡因子是它的左子树的高度减去它的右子树的

JavaScript之jQuery-3 jQuery操作DOM(查询、样式操作、遍历节点、创建插入删除、替换、复制)

一.jQuery操作DOM - 查询 html操作 - html(): 读取或修改节点的HTML内容,类似于JavaScript中的innerHTML属性 文本操作 - text(): 读取或修改节点的文本内容,类似于JavaScript中的textContent属性 值操作 - val(): 读取或修改节点的value属性值,类似于 JavaScript 中的value值 属性操作 - attr(): 读取或者修改节点的属性 - removeAttr(): 删除节点的属性 二.jQuery操作