天天看点

数据结构与算法(C语言)之循环链表(单链表)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
/*
将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表
    注:并不是说循环链表一定要有头结点
    其实循环链表单链表的主要差异就在于循环的判断空链表的条件上,
    原来判断head->next是否为null,现在则是head->next是否等于head
    -初始化部分:ds_init.c
    -插入部分:ds_insert.c
    -删除部分:ds_delete.c
    -返回结点所在位置:ds_search.c
*/
/*链表存储结构的定义*/
typedef struct CLinkList
{
    int data;
    struct CLinkList *next;
}node;

/*初始化循环链表*/
void ds_init(node **pNode)
{
    int item;
    node *temp;
    node *target;

    printf("输入结点的值,输入0完成初始化\n");

    while(1)
    {
        scanf("%d",&item);
        fflush(stdin);

        if(item==0)
            return;
        if(*pNode==NULL)
        /*循环链表中只有一个结点*/
        {
            *pNode=(node *)malloc(sizeof(struct CLinkList));
            if(!(*pNode))
                exit(0);
            (*pNode)->data=item;
            (*pNode)->next=*pNode;
        }
        else
        {

            /*找到next指向第一个结点的结点*/
            for(target=(*pNode);target->next!=(*pNode);target=target->next)
                ;
            /*生成一个新的结点*/
            temp=(node *)malloc(sizeof(struct CLinkList));

            if(!temp)
                exit(0);
            temp->data=item;
            temp->next=*pNode;
            target->next=temp;
        }
    }
}
/*插入结点
参数:链表的第一个结点,出入位置*/
void ds_insert(node **pNode,int i)
{
    node *temp;
    node *target;
    node *p;
    int item;
    int j;

    printf("输入要插入结点的值:");
    scanf("%d",&item);

    if(i==1)
    {
        temp=(node *)malloc(sizeof(struct CLinkList));

        if(!temp)
            exit(0);
        temp->data=item;

        /*寻找到最后一个结点*/
        for(target=(*pNode);target->next!=(*pNode);target=target->next)
            ;
        temp->next=(*pNode);
        target->next=temp;
        *pNode=temp;
    }
    else
    {
        target=*pNode;

        for(j=1;j<(i-1);++j)
        {
            target=target->next;
        }

        temp=(node *)malloc(sizeof(struct CLinkList));

        if(!temp)
            exit(0);
        temp->data=item;
        p=target->next;
        target->next=temp;
        temp->next=p;
    }
}
/*删除结点*/
void ds_delete(node **pNode ,int i)
{
    node *target;
    node *temp;
    int j=1;

    if(i==1)
    {
        //删除的是第一个结点
        /*找到最后一个结点*/
        for(target=*pNode;target->next!=*pNode;target=target->next)
            ;
        temp=*pNode;
        *pNode=(*pNode)->next;
        target->next=*pNode;
        free(temp);
    }
    else
    {
        target=*pNode;

        for(;j<i-1;j++)
            target=target->next;
        temp=target->next;
        target->next=temp->next;
        free(temp);
    }
}
/*返回结点所在的位置*/
int ds_search(node *pNode,int elem)
{
    node *target;
    int i=1;

    for(target=pNode;target->data!=elem&&target->next!=pNode;target=target->next,++i)
        ;
    if(target->next==pNode)
        return 0;
    else
        return i;
}
/*遍历*/

void ds_traverse(node *pNode)
{
    node *temp;
    temp=pNode;
    printf("***********************链表中的元素***********************\n");
    do
    {
        printf("%d ",temp->data);
    }while((temp=temp->next)!=pNode);
    printf("\n");
}
/* 初始条件:线性表PNode已存在。操作结果:若pNode为空表,则返回TRUE,否则返回FALSE */
int ListEmpty(node *pNode)
{
    if(pNode->next==pNode)
        return FALSE;
    else
        return TRUE;
}
/*链表长度*/
int ListLength(node *pNode)
{
    int i=1;
    node *p=pNode->next;

    while(p!=pNode)
    {
        i++;
        p=p->next;
    }
    return i;
}
/*显示链表操作的说明*/
void showHomepage()
{
    puts("请输入你要操作的编号:");
    printf("1.初始化链表    2.插入结点\n");
    printf("3.删除结点      4.返回结点值\n");
    printf("5.遍历链表      6.判断链表是否为空\n");
    printf("7.链表长度      0.退出\n");
}
int main()
{
    node *pHead=NULL;
    char cpp;
    int find;
   showHomepage();
    while(cpp!='0')
    {
        scanf("%c",&cpp);
        switch(cpp)
        {
        case '1':
            ds_init(&pHead);
            printf("\n");
            ds_traverse(pHead);
            showHomepage();
            break;
        case '2':
            printf("请输入要插入的位置:");
            scanf("%d",&find);
            ds_insert(&pHead,find);
            printf("在位置%d插入值后:\n",find);
            ds_traverse(pHead);
            printf("\n");
            showHomepage();
            break;
        case '3':
            printf("输入需要删除的结点位置:");
            scanf("%d",&find);
            ds_delete(&pHead,find);
            printf("删除第%d结点后:\n",find);
            ds_traverse(pHead);
            printf("\n");
            showHomepage();
            break;
        case '4':
            printf("你要查找的值:");
            scanf("%d",&find);
            printf("元素%d所在位置:%d\n",find,ds_search(pHead,find));
            printf("\n");
            showHomepage();
            break;
        case '5':
            ds_traverse(pHead);
            printf("\n");
            showHomepage();
            break;
        case '6':
            if(!ListEmpty(pHead))
                puts("链表为空!");
            else
                puts("链表不为空!");
            showHomepage();
            break;
        case '7':
            printf("链表的长度为:%d\n",ListLength(pHead));
            showHomepage();
            break;
        case '0':
            exit(0);
        }
    }
    return 0;
}