带头双向带环链表

原创 2018年04月14日 23:49:04
  1. 初始化链表
  2. 尾插
  3. 尾删
  4. 头插
  5. 头删
  6. 查询元素
  7. 往指定位置之前插入一个元素
  8. 往指定位置之后插入一个元素
  9. 删除指定元素
  10. 删除指定元素的第一次出现
  11. 删除所有指定元素
  12. 求链表的长度
  13. 判断链表是否为空(0为空,1为非空)

dlinknode.h:

#pragma once

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

typedef char DLinkType;

typedef struct DLinkNode{
    DLinkType data;
    struct DLinkNode* next;
    struct DLinkNode* prev; 
}DLinkNode;

DLinkNode* CreateNode();

void DeleteNode(DLinkNode* head);


void DLinkNodeInit(DLinkNode** head);

DLinkNode* DLinkNodePushBack(DLinkNode* head,DLinkType value);

void DLinkNodePopBack(DLinkNode* head);

void DLinkNodePushTop(DLinkNode* head,DLinkType value);

void DLinkNodePopTop(DLinkNode* head);

DLinkNode* DLinkNodeFind(DLinkNode* head,DLinkType value);

void DLinkNodeInsert(DLinkNode* pos,DLinkType value);

void DLinkNodeInsertAfter(DLinkNode* pos,DLinkType value);

void DLinkNodeErase(DLinkNode* head,DLinkNode* pos);

void DLinkNodeRemove(DLinkNode* head,DLinkType value);

void DLinkNodeRemoveAll(DLinkNode* head,DLinkType value);

size_t DLinkNodeSize(DLinkNode* head);

int DLinkNodeEmpty(DLinkNode* head);

dlinknode.c:

#include "dlinknode.h"

DLinkNode* CreateNode()
{
    DLinkNode* head = (DLinkNode*)malloc(sizeof(DLinkNode));
    head->next = NULL;
    head->prev = NULL;
}

void DeleteNode(DLinkNode* node)
{
    free(node);
    node = NULL;
}


void DLinkNodeInit(DLinkNode** head)
{
    *head = CreateNode();
    (*head)->next = *head;
    (*head)->prev = *head;
}

DLinkNode* DLinkNodePushBack(DLinkNode* head,DLinkType value)
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* cur = CreateNode();
    cur->data = value;

    DLinkNode* file = head;
    DLinkNode* last = head->prev;
    cur->prev = last;
    cur->next = file;
    file->prev = cur;
    last->next = cur;
    return cur;
}

void DLinkNodePopBack(DLinkNode* head)
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* to_delete = head->prev;
    DLinkNode* cur = to_delete->prev;
    DLinkNode* file = head;
    cur->next = file;
    file->prev = cur;
    DeleteNode(to_delete);
}

void DLinkNodePushTop(DLinkNode* head,DLinkType value)
{
    if(head == NULL)
    {
        return;
    }

    DLinkNode* new_node = CreateNode();
    new_node->data = value;
    DLinkNode* cur = head->next;
    DLinkNode* file = head;

    new_node->next = cur;
    new_node->prev = file;
    cur->prev = new_node;
    file->next = new_node;
}

void DLinkNodePopTop(DLinkNode* head)
{
    if(head == NULL)
    {
        return;
    }

    DLinkNode* to_delete = head->next;
    DLinkNode* cur = to_delete->next;
    DLinkNode* file = head;

    file->next = cur;
    DeleteNode(to_delete);
}

DLinkNode* DLinkNodeFind(DLinkNode* head,DLinkType value)
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* cur = head;
    while(cur->next != head)
    {
        if(cur->data == value)
        {
            return cur;
        }
        cur = cur->next;
    }
    if(cur->data == value)
    {
        return cur;
    }
    return NULL;
}

void DLinkNodeInsert(DLinkNode* pos,DLinkType value)
{
    if(pos == NULL)
    {
        return;
    }
    DLinkNode* new_node = CreateNode();
    new_node->data = value;
    DLinkNode* cur = pos->prev;
    cur->next = new_node;
    pos->prev = new_node;
    new_node->next = pos;
    new_node->prev = cur;
}

void DLinkNodeInsertAfter(DLinkNode*pos,DLinkType value)
{
    if(pos == NULL)
    {
        return;
    }
    DLinkNode* new_node = CreateNode();
    new_node->data = value;
    DLinkNode* cur = pos->next;
    pos->next = new_node;
    cur->prev = new_node;
    new_node->next = cur;
    new_node->prev = pos;
}

void DLinkNodeErase(DLinkNode* head,DLinkNode* pos)
{
    if(head == NULL || pos == NULL)
    {
        return;
    }

    DLinkNode* cur = head->next;
    while(cur != pos && cur != head)
    {
        cur = cur->next;
    }
    if(cur == pos)
    {
        DLinkNode* file = pos->next;
        cur = cur->prev;
        cur->next = file;
        file->prev = cur;
        DeleteNode(pos);
    }
}

void DLinkNodeRemove(DLinkNode* head,DLinkType value)
{
    if(head == NULL)
    {
        return;
    }

    DLinkNode* cur = head->next;

    while(cur->data != value && cur != head)
    {
        cur = cur->next;
    }
    if(cur->data == value)
    {
        DLinkNode* file = cur->next;
        DLinkNode* to_delete = cur;
        cur = cur->prev;
        cur->next = file;
        file->prev = cur;
        DeleteNode(to_delete);
    }
}

void DLinkNodeRemoveAll(DLinkNode* head,DLinkType value)
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* cur = head->next;
    while(cur != head)
    {
        if(cur->data != value)
        {
            cur = cur->next;
        }
        else
        {
            DLinkNode* file = cur->next;
            DLinkNode* to_delete = cur;
            cur = cur->prev;
            cur->next = file;
            file->prev = cur;
            DeleteNode(to_delete);
        }
    }
}

size_t DLinkNodeSize(DLinkNode* head)
{
    if(head == NULL)
    {
        return 0;
    }
    size_t count = 0;
    DLinkNode* cur = head->next;
    while(cur != head)
    {
        cur = cur->next;
        count++;
    }
    return count;
}

int DLinkNodeEmpty(DLinkNode* head)
{
    if(head == NULL)
    {
        return 0;
    }
    DLinkNode* cur = head;
    if(cur->next == head)
    {
        return 0;
    }
    return 1;
}

//------------------------------------------------------------
//-----测试函数
//------------------------------------------------------------

#define LINE printf("-------------------------------------------------\n");

void DLinkNodePrint(DLinkNode* head,const char* msg)
{
    printf("%s\n",msg);
    DLinkNode* cur = head->next;
    printf("[澶磡%p]",&(head->data));
    printf("<->");
    int i = 0;
    while(cur->next != head)
    {
        printf("[%c|%p]",cur->data,&(cur->data));
        printf("<->");
        cur = cur->next;
        i++;
    }
    if(cur->next == head && i != 0)
    {
        printf("[%c|%p]",cur->data,&(cur->data));
        printf("<->");
    }
    printf("[澶磡%p]\n",&(head->data));
}

void testDLinkNodePushBack()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');

    DLinkNodePrint(head,"DLinkNodePushBack");
}

void testDLinkNodePopBack()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');

    DLinkNodePopBack(head);
    DLinkNodePrint(head,"DLinkNodePopBack");
}

void testDLinkNodePushTop()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');

    DLinkNodePushTop(head,'z');
    DLinkNodePrint(head,"DLinkNodePushTop");
}

void testDLinkNodePopTop()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');

    DLinkNodePopTop(head);
    DLinkNodePrint(head,"DLinkNodePopTop");
}

void testDLinkNodeFind()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');

    DLinkNode* cur = DLinkNodeFind(head,'c');
    DLinkNodePrint(head,"DLinkNodeFind");
    if(cur == NULL)
    {
        printf("not find !\n");
    }
    else
    {
        printf("find it:[%c|%p]\n",cur->data,&(cur->data));
    }
}

void testDLinkNodeInsert()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNode* pos = DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');

    DLinkNodePrint(head,"DLinkNodeInsert");
    DLinkNodeInsert(pos,'z');
    DLinkNodePrint(head,"DLinkNodeInsert");
}

void testDLinkNodeInsertAfter()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNode* pos = DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');

    DLinkNodePrint(head,"DLinkNodeInsertAfter");
    DLinkNodeInsertAfter(pos,'z');
    DLinkNodePrint(head,"DLinkNodeInsertAfter");
}

void testDLinkNodeErase()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNode* pos = DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');

    DLinkNodeErase(head,pos);
    DLinkNodePrint(head,"DLinkNodeErase");
}

void testDLinkNodeRemove()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');

    DLinkNodeRemove(head,'c');
    DLinkNodePrint(head,"DLinkNodeRemove");
}

void testDLinkNodeRemoveAll()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');
    DLinkNodePushBack(head,'c');

    DLinkNodeRemoveAll(head,'c');
    DLinkNodePrint(head,"DLinkNodeRemoveAll");
}

void testDLinkNodeSize()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'d');

    int ret = DLinkNodeSize(head);
    DLinkNodePrint(head,"DLinkNodeSize");
    printf("DLinkNodeSize is :%d\n",ret);
}

void testDLinkNodeEmpty()
{
    LINE;
    DLinkNode* head = NULL;
    DLinkNodeInit(&head);

    DLinkNodePushBack(head,'a');
    DLinkNodePushBack(head,'c');
    DLinkNodePushBack(head,'b');
    DLinkNodePushBack(head,'c');

    int ret = DLinkNodeEmpty(head);
    DLinkNodePrint(head,"DLinkNodeEmpty");
    printf("%d\n",ret);
}

int main()
{
    testDLinkNodePushBack();
    testDLinkNodePopBack();
    testDLinkNodePushTop();
    testDLinkNodePopTop();
    testDLinkNodeFind();
    testDLinkNodeInsert();
    testDLinkNodeInsertAfter();
    testDLinkNodeErase();
    testDLinkNodeRemove();
    testDLinkNodeRemoveAll();
    testDLinkNodeSize();
    testDLinkNodeEmpty();
    return 0;
}













这里写图片描述
这里写图片描述

*[Lintcode]带环链表 II

给定一个链表,如果链表中存在环,则返回到链表中环的起始节点的值,如果没有环,返回null。 样例 给出 -21->10->4->5, tail connects to node index 1,返回...
  • jc69186918
  • jc69186918
  • 2017-02-07 11:40:12
  • 308

单链表面试题系列之带环链表的入口点

***单链表操作之带环链表的入口点*** //  本篇博文阐述如何找到带环链表的入口点,那么,首先有必要阐述一下什么是带环链表?如何判断链表是否带环? 带环链表: 即链表中有循环的部分,通...
  • bitboss
  • bitboss
  • 2016-06-12 19:46:18
  • 2781

LintCode(103)带环链表 II

题目 给定一个链表,如果链表中存在环,则返回到链表中环的起始节点的值,如果没有环,返回null。 您在真实的面试中是否遇到过这个题?  Yes 样例 ...
  • fly_yr
  • fly_yr
  • 2016-05-31 21:08:26
  • 3659

单链表判断是否带环,环的接入点

1、是否带环判断:使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。2、环的接入点:碰撞点p到连接点的距...
  • qq_24980287
  • qq_24980287
  • 2015-07-15 23:35:16
  • 269

Java实现-带环链表

/** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ...
  • qq_14927217
  • qq_14927217
  • 2017-06-06 22:32:27
  • 151

如何找到带环链表的入口节点?

2种思路: 首先我们假设有个带环链表list1,如图我们可以这么做: 这样问题就转换成了如何求出2个不带环链表的相交节点很明显你会问如何在环中找到一个节点,你不可能去遍历(会死循环),有这样一...
  • fengasdfgh
  • fengasdfgh
  • 2016-10-24 02:07:43
  • 676

每日一题(16) - 如何得到两个带环且相交的单链表的交点

题目来自编程之美 题目:如何得到两个带环且相交的单链表的交点 分析:具体参考单链表面试题 情况1:相交的点,在环外 思路:使用指针追赶的方法。 1、求两个链表A和B的长度Length...
  • insistGoGo
  • insistGoGo
  • 2013-06-24 19:47:40
  • 1770

双向,带头节点,带环链表的基本操作

        前面已经介绍过了不带头节点,不带环的双向链表,以下将介绍带头节点,带环的双向链表的基本操作。        不带头结点时,用一个头指针代表整个链表。带头节点,则用头结点来表示整个链表。...
  • sandmm112
  • sandmm112
  • 2018-04-08 22:07:33
  • 24

判断链表是否带环,以及环的入口

给出一个链表,先判断链表是否带环,如果带环,求出环的入口。 判断是否带环:用快慢指针。快指针每走两步,慢指针走一步,如果两者在某个点处相 遇,则链表带环。 下边给出函数的实现代码: typed...
  • peiyao456
  • peiyao456
  • 2016-06-24 13:39:19
  • 1763

链表面试题----判断一个单链表是否带环,若带环,求入口点和环的长度

题目:不用标志位,最多只能用两个指针,如何判断一个单链表是否带环? 分析:定义两个指针slow和fast,slow每次递增一步,fast每次递增两步,如果两者相遇(相等),代表该链表带环,否则没环。...
  • scmuzi18
  • scmuzi18
  • 2017-05-07 12:10:13
  • 172
收藏助手
不良信息举报
您举报文章:带头双向带环链表
举报原因:
原因补充:

(最多只允许输入30个字)