Linux学习之路(10)

本文详细介绍了双向循环链表的创建、头插、尾插、随机插入、删除指定位置及逆序等操作的实现过程。通过具体代码示例,深入解析了双向循环链表的数据结构和关键算法。

双向循环链表

main.c

#include <stdio.h>
#include "Linklist.h"


int main()
{
    List *ls = CreatList();
    
    if(NULL == ls)
    {
        printf("创建失败\n");
    }
    else
    {
        printf("创建成功\n");
    }
    
    //头插
    Insert_Head(ls, 1);
    Insert_Head(ls, 5);
    Insert_Head(ls, 12);
    Insert_Head(ls, 12);
    Insert_Head(ls, 15);
    Insert_Head(ls, 18);
    Insert_Head(ls, 18);
    Insert_Head(ls, 21);
    Display(ls);
    
    //尾插
    Insert_Last(ls, 1);
    Insert_Last(ls, 5);
    Insert_Last(ls, 12);
    Insert_Last(ls, 12);
    Insert_Last(ls, 15);
    Insert_Last(ls, 18);

    Display(ls);
    
    //随机插入
    Insert_Pos(ls, 3, 11);
    Display(ls);
    
    //指定位置删除
    Delete_Pos(ls, 3);
    Display(ls);
    
    //逆序链表
    Reverse(ls);
    Display(ls);
    
    Destroy(ls);
    

    
    
    return 0;
}

 

Linklist.h

#ifndef _LINK_LIST
#define _LINK_LIST


typedef enum {TRUE, FALSE, ERROR} BOOL;

typedef int Data;

typedef struct _Node
{
    Data data;
    struct _Node *next;
    struct _Node *pre;
}Node;

typedef struct _List
{
    Node *head;
}List;

//创建链表
List *CreatList();            

//头插
BOOL Insert_Head(List* ls, Data data);

//尾插
BOOL Insert_Last(List* ls, Data data);

//随机插入
BOOL Insert_Pos(List* ls, int Pos, Data data);

//删除指定位置文件
BOOL Delete_Pos(List* ls, int Pos);

//逆序链表
BOOL Reverse(List *ls);

//打印链表
void Display(List *ls);

void Destroy(List *ls);


#endif   //_LINK_LIST

 

 

list.c

#include "Linklist.h"
#include <stdio.h>
#include <stdlib.h>

//创建链表
List *CreatList()
{
    List *ls = (List *)malloc(sizeof(List)/sizeof(char));
    if(NULL == ls)
        return NULL;
    
    ls->head = (Node *)malloc(sizeof(Node)/sizeof(char));
    if(NULL == ls->head)
    {
        free(ls);
        return NULL;
    }
    
    ls->head->next = ls->head;
    ls->head->pre = ls->head;
    
    return ls;
}

//头插
BOOL Insert_Head(List* ls, Data data)
{
    if(NULL == ls)
    {
        return ERROR;
    }
    
    Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
    if(NULL == node)
    {
        return ERROR;
    }
    
    node->data = data;
    ls->head->next->pre = node;
    node->next = ls->head->next;
    node->pre = ls->head;
    ls->head->next = node;
    
    
    return TRUE;
}
    
//尾插
BOOL Insert_Last(List* ls, Data data)
{
    if(NULL == ls)
    {
        return ERROR;
    }
    
    Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
    if(NULL == node)
    {
        return ERROR;
    }

    node->data = data;
    node->next = NULL;
    
    Node *tmp = ls->head;
    while(tmp->next != ls->head)
    {
        tmp = tmp->next;
    }
    
    tmp->next = node;
    node->pre = tmp;
    node->next = ls->head;
    ls->head->pre = node;
    
    return TRUE;
}

//随机插入
BOOL Insert_Pos(List* ls, int Pos, Data data)
{
    if(NULL == ls || Pos < 1)
    {
        return ERROR;
    }
    
    Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
    if(NULL == node)
    {
        return ERROR;
    }
    
    Node *tmp = ls->head;
    int i = 0;
    for (i = 0; i < Pos-1; i++)
    {
        tmp = tmp->next;
        if(NULL == tmp)
        {
            printf("插入位置越界:%d\n",Pos);
            return ERROR;
        }
    }
    node->data = data;
    
    tmp->next->pre = node;
    node->next = tmp->next ;
    tmp->next = node;
    node->pre = tmp;
    
    return TRUE;
    
}

//指定位置删除
BOOL Delete_Pos(List* ls, int Pos)
{
    if(NULL == ls || Pos < 1)
    {
        return ERROR;
    }
    
    Node *tmp = ls->head;
    int i = 0;
    for (i = 0; i < Pos-1; i++)
    {
        tmp = tmp->next;
        if(NULL == tmp)
        {
            printf("删除位置越界:%d\n",Pos);
            return ERROR;
        }
    }
    Node *p = tmp->next;
    tmp->next = p->next;
    p->next->pre = tmp;
    free(p);
    return TRUE;
}
    
//打印链表
void Display(List* ls)
{
    if(NULL == ls)
    {
        return ;
    }
    
    Node *tmp = ls->head->next;     //第一个节点
    while(tmp != ls->head)
    {
        printf("%-4d",tmp->data);
        tmp = tmp->next;
    }
    
    printf ("\n");
    
}

//逆序
BOOL Reverse(List *ls)
{
    if(NULL == ls || NULL == ls->head || NULL == ls->head->next || NULL == ls->head->next->next)
    {
        return ERROR;
    }
    
    Node *cur = ls->head->next;
    
    while(cur->next != ls->head)
    {
        Node *p = cur->next;
        cur->next = cur->pre;
        cur->pre = p;
        cur = p;
    }
    
    ls->head->next->next = ls->head;
    ls->head->next = cur;
    cur->next = cur->pre;
    cur->pre = ls->head;
    
    return TRUE;
}
    
    
//销毁链表    
void Destroy(List *ls)
{
    if(NULL == ls)
        return ;
    
    free(ls->head);
    free(ls);
}

 

循环链表和双向链表的结合,双向链表和循环链表都是由单向链表发展出来的。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值