双向循环链表

双向循环链表可理解为一个闭环,一般为了区别和操作方便,头结点不存内容。以下是整个过程的代码实现
#include <stdio.h>
typedef int DATATYPE;//定义int的别名,以防止以后结点内容不是int了可以方便替换
//定义链表结点结构体
struct node
{
    DATATYPE data;//数据域
    struct node *left;//指向前一个结点,用left其实更便于理解
    struct node *right;//指向后一个结点用right也是为了便于理解,next也不错
};
typedef struct node Node;//定义别名,方便书写
 
Node * createDList();//创建双向循环链表
int insertList1(Node *head, DATATYPE data);//头插法插入
int insertList2(Node *head, DATATYPE data);//尾插法插入
void printDlist(Node * head);//打印链表内容
Node *searchNode(Node *head, DATATYPE find);//查找链表中的元素,双向查找
void sortList1(Node *head, int len);//交换内容排序 基于冒泡
void sortList2(Node *head, int len);//交换指针排序 基于冒泡
void sortList3(Node *head, int len);//基于选择排序的交换内容排序
int deleteNode(Node *head, DATATYPE data);//删除指定节点
int lenList(Node *head);//求双向循环链表的长度
void destroyList(Node *head);//求双向循环链表的长度
 
int main(void)
{
    Node *head = createDList();//创建链表
    printf("head=%p\n", head);
    int i = 0;
    for (i = 7; i >= 0; i--)//为链表赋初始测试值
//      insertList1(head, i);
        insertList2(head, i);
    printDlist(head);
    printf("——————\n");
    DATATYPE find = 3;//测试查找函数
    Node *search=searchNode(head, find);
    if (search != NULL)
        printf("search=%d\n", search->data);
    else
        printf("no such number\n");
    DATATYPE data = 0;
    deleteNode(head, data);//测试删除函数
    int len = lenList(head);//测试求长度函数
    printf("len=%d\n",len);
//  sortList1(head, len);//测试排序函数
//  sortList2(head, len);
    sortList3(head, len);
    printDlist(head);
    destroyList(head);//销毁所有结点
    printf("销毁后的头节点:=%p\n",head->right);
    printf("sizeof(head)=%d\n",sizeof(head));
    return 0;
}
//创建双向循环链表,只需要返回一个头结点就好
//双向循环链表,就想一个闭环一样的概念,一般头结点中不存储内容
Node * createDList()
{
    Node *head = (Node *)malloc(sizeof(Node));
    if (head)
    {
        head->left = head;
        head->right = head;
        return head;
    }
    else
        return NULL;
}
//头插法插入,每次插入在头结点后紧跟着
int insertList1(Node *head, DATATYPE data)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (newNode)
    {
        newNode->data = data;
 
        newNode->left = head;
        newNode->right = head->right;
 
        head->right = newNode;
        newNode->right->left = newNode;
 
        return 1;
    }
    else
        return -1;
}
//尾插法插入,每次插入在头结点之前
int insertList2(Node *head, DATATYPE data)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (newNode)
    {
        newNode->data = data;
        head->left->right = newNode;
        newNode->left = head->left;
        newNode->right = head;
        head->left = newNode;
        return 1;
    }
    return -1;
}
//打印链表内容
void printDlist(Node * head)
{
    Node *p = head->right;
    while (p != head)
    {
        printf("%d\n", p->data);
        p = p->right;
    }
}
//查找链表中的元素,双向查找
Node *searchNode(Node *head, DATATYPE find)
{
    Node *left = head;//left表示一个结点的前驱结点,初始值是头结点
    Node *right = head;//right表示一个结点的后继结点,初始值是头结点
    do
    {
        left = left->left;//移动向前一个
        right = right->right;//移动向后一个
        if (left->data == find)//如果此时结点发现查找内容,就返回结点信息
            return left;
        if (right->data == find)//如果此时结点发现查找内容,就返回结点信息
            return right;  
    } while (left != right && left->left!=right);//当两个结点相遇或者错过时候终止循环
    //如果除了头结点是偶数个,则相互错过时候终止
    //如果除了头结点是奇数个,则相遇时候终止查找
    return NULL;   
}
//交换内容排序 基于冒泡
void sortList1(Node *head, int len)
{
    int i = 0, j = 0;
    Node *p, *q;
    for (i = 0; i < len - 1; i++)
    {
        p = head->right;
        q = p->right;
        for (j = 0; j < len - 1 - i; j++)
        {
            if (p->data<q->data){
                p->data ^= q->data;
                q->data ^= p->data;
                p->data ^= q->data;
            }
            p = p->right;
            q = q->right;
        }
    }
     
}
//交换指针排序 基于冒泡
void sortList2(Node *head, int len)
{
    Node *p, *q;
    int i = 0, j = 0;
    for (i = 0; i < len - 1; i++)
    {
        p = head->right;
        q = p->right;
        for (j = 0; j < len - 1-i; j++)
        {
            if (p->data < q->data){
                q->left = p->left;
                p->left->right = q;
                p->right = q->right;
                q->right->left = p;
                q->right = p;
                p->left = q;
 
                q = p->right;
                 
            }
            else{
                p = p->right;
                q = q->right;
            }
             
        }
    }
}
//基于选择排序的交换内容排序
void sortList3(Node *head, int len)
{
    Node *p, *q, *max, *temp;
    DATATYPE t;
    p = head->right;
    q = p->right;
    int i = 0, j = 0;
    for (i = 0; i < len-1 ; i++)
    {
        if (p == head)
            break;
        max = p;
        q = p;
        for (j = i; j < len; j++)
        {
            if (q == head)
                break;
            if (max->data > q->data)
                max = q;
            q = q->right;
        }
        if (max != p)
        {
            t = max->data;
            max->data = p->data;
            p->data = t;       
        }
        p = p->right;
    }   
}
//基于选择排序的交换指针排序,写了但是一直出问题?
//删除指定节点
int deleteNode(Node *head, DATATYPE data)
{
    Node *search = searchNode(head, data);
    if (search){
        search->left->right = search->right;
        search->right->left = search->left;
        free(search);
        return 1;
    }
    return 0;
}
//求双向循环链表的长度
int lenList(Node *head)
{
    Node *p = head;
    int len = 0;
    while (p->right != head){
        len++;
        p = p->right;
    }
    return len;
}
//销毁所有记录
void destroyList(Node *head)
{
    Node *p = head->right;
    while (p != head)
    {
        p = p->right;
        free(p->left);
    }
    free(head);
     
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值