单循环链表的实现

来源:互联网 发布:云房数据研究中心出品 编辑:程序博客网 时间:2024/04/28 00:07

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

//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;}
0 0