单循环链表的实现

对于单循环链表:
它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

//circular_linked_list .h  头文件
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdlib.h>
typedef struct round
{
    int data;
    struct round *pNext;
}NODE, *PNODE;


PNODE create();

void judge(PNODE phead);

void traverse_list(PNODE pHead);

int is_empty(PNODE pHead);

int lenght_list(PNODE pHead);

int insert_list(PNODE pHead, int n, int val);

int delete_list(PNODE pHead, int n, int *pVal);

void soert_list(PNODE pHead, char ch);

int*  find(PNODE pHead, int a, int *sv);

PNODE DestroyList(PNODE pHead);

接下来是完成算法的文件

#define _CRT_SECURE_NO_WARNINGS 1


#include"circular_linked_list .h"


//判断malloc是否开辟成功
void judge(PNODE phead)
{
    if (phead == NULL)
    {
        printf("动态开辟失败");
        exit(1);
    }
}


//创建循环链表
PNODE create()
{
    int count = 0;
    int val = 0;
    PNODE phead = (PNODE)malloc(sizeof(NODE));
    phead->pNext = phead;
    judge(phead);
    PNODE ptail = phead;
    ptail->pNext = NULL;
    printf("输入你所需要创建的节点个数:");
    scanf("%d", &count);
    for (int i = 0; i < count; i++)
    {
        PNODE pnew = (PNODE)malloc(sizeof(NODE));
        judge(pnew);
        printf("输入在第%d节点的值:", i + 1);
        scanf("%d", &val);
        pnew->data = val;
        ptail->pNext = pnew;
        pnew->pNext =phead;
        ptail = pnew;

    }
    return phead;
}



//遍历整个循环链表
void traverse_list(PNODE phead)
{
    judge(phead);
    PNODE p = phead->pNext;
    while (p!=phead)
    {
        printf("%d  ", p->data);
        p = p->pNext;
    }
    printf("\n");
}

//判断链表是否为空
int is_empty(PNODE pHead)
{
    if (pHead == pHead->pNext)
    {
        return 1;
    }

    return 0;
}


//求链表的长度
int lenght_list(PNODE pHead)
{
    int len = 0;
    judge(pHead);
    PNODE p = pHead->pNext;
    while (p)
    {
        if (p != pHead)
        {
            len++;
            p = p->pNext;
        }
        else
            break;
    }
    return len;
}



//插入在某个位置插入数据
int insert_list(PNODE pHead, int n, int val)
{
    judge(pHead);
    PNODE p = pHead;
    int i = 0;
    //在这里进行的是寻找咱们所需要插入的那个节点
    while (NULL != p&&i < n - 1)
    {
        p = p->pNext;
        i++;
    }

    if (n <= 0 || n>lenght_list(pHead))
    {
        return 0;
    }
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    judge(pNew);
    pNew->data = val;
    pNew->pNext = p->pNext;
    p->pNext = pNew;
    if (p == pHead)
        pHead = pNew;
    return 1;
}



//删除指定位置节点
int delete_list(PNODE pHead, int n, int *pVal)
{
    judge(pHead);
    PNODE p = pHead;
    int i = 0;
    while (i<n-1)
    {
        p = p->pNext;
        i++;
    }
    if (n <= 0 || n>lenght_list(pHead))
    {
        return 0;
    }
    PNODE q = p->pNext;
    *pVal = q->data;
    //输出p节点后的节点,这里要注意的是一定要记得free;
    p->pNext = q->pNext;
    if (pHead == q)
        pHead = q;
    free(q);
    return 1;
}

//链表排序
//链表排序最适合的是冒泡排序法。
void soert_list(PNODE pHead,char ch)
{
    judge(pHead);
    if ('>'==ch)
    {
        for (PNODE p1 = pHead->pNext; p1 != pHead; p1=p1->pNext)
        {
            for (PNODE p2 = pHead->pNext; p2 != pHead; p2 = p2->pNext)
            {
                if ((p1->data) > (p2->data))
                {
                    int tmp = p1->data;
                    p1->data = p2->data;
                    p2->data = tmp;
                }
            }
        }
    }
    else if ('<' == ch)
    {
        for (PNODE p1 = pHead->pNext; p1 != pHead; p1 = p1->pNext)
        {
            for (PNODE p2 = pHead->pNext; p2 != pHead; p2 = p2->pNext)
            {
                if ((p1->data) < (p2->data))
                {
                    int tmp = p1->data;
                    p1->data = p2->data;
                    p2->data = tmp;
                }
            }
        }
    }
}

//查找某个元素的位置
int*  find(PNODE pHead, int a, int *sv)
{
    judge(pHead);
    int count = 1;
    PNODE p = pHead->pNext;
    while (p !=pHead)
    {
        p = p->pNext;
        count++;
        if (a == p->data)
        {
            *sv = count;
            return sv;
        }
    }
    return NULL;
}


//销毁链表
PNODE DestroyList(PNODE pHead)
{
    PNODE q, p ;
    p = q = NULL;
    p = pHead;
    while (p->pNext != pHead)
    {
        q = p->pNext;//让q指向下一个节点
        p ->pNext= q->pNext;//p存储了q。下一个节点的地址;
        free(q);
    }
    free(pHead);
    return NULL;
}

接下来是测试函数的文件:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdlib.h>
#include"circular_linked_list .h"
int main()
{
    int len = 0;
    //接下来进行循环链表的操作
    //首先创建循环链表
    PNODE phead = NULL;


    //测试创建循环链表
    phead=create(phead);

    //测试遍历循环链表
    traverse_list(phead);


    //测试判断链表是否为空
    if (is_empty(phead) == 0)
        printf("链表非空\n");
    else
        printf("链表为空\n");


    //测试求循环链表的长度
    printf("此循环链表的长度为:\n");
    len = lenght_list(phead);
    printf("%d\n",len);


    //测试插入在某个位置插入数据
    int n = 0;
    int val = 0;
    printf("请输入你所需要插入的位置:");
    scanf("%d", &n);
    printf("请输入你所需要插入的数据:");
    scanf("%d", &val);
    if (insert_list(phead, n, val) == 0)
        printf("插入失败\n");
    else
        printf("插入成功\n");
    traverse_list(phead);


    //测试删除指定位置的节点
    int del_Val = 0;
    printf("请输入你所需要删除的节点所在的位置:");
    scanf("%d", &n);
    if (delete_list(phead, n, &del_Val))
    {

        printf("删除元素%d成功\n", del_Val);
    }
    else
    {
        printf("删除元素%d失败\n", del_Val);
    }
    traverse_list(phead);


    //测试链表元素查找,并且返回所在位置
    int a = 0;
    int find_position = 0;
    printf("输入你所要查找的元素");
    scanf("%d", &a);
    if (find(phead, a, &find_position) == NULL)
        printf("该循环链表中没有这一个元素。\n");
    else
    {
        printf("所查找的元素位置位于:\n");
        printf("%d\n", find_position);
    }


    //测试循环链表的排序
    char ch = 0;
    printf("选择循环链表的排序方式(输入'>'或者'<'):\n");
    fflush(stdin);
    scanf("%c",&ch);
    soert_list(phead,ch);
    traverse_list(phead);


    //测试销毁链表
    phead=DestroyList(phead);
    traverse_list(phead);


    system("pause");
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值