循环链表

来源:互联网 发布:outlook邮箱的smtp端口 编辑:程序博客网 时间:2024/06/18 10:04

循环链表

  循环链表和普通链表差别不大,只是将尾结点指向头结点。
  如果设一个尾指针指向尾结点可以使在链尾添加结点和两链表合并的操作变得简单快捷,并且尾指针所指向的结点指向的结点即为头结点,因此又可省略头指针。

示例代码
添加了尾指针,并且保留了头指针

#include <stdio.h>typedef struct criList{    int data;    struct criList *next;}criList;criList* createNullList();         /**创建空链表的函数的声明**/int isNullList(criList *head);      /**判断是否链表是否为空的函数的声明(Y-1,N-0)**/int insertNode(criList **rnode, int n); /**在链尾插入结点的函数的声明**/int unionList(criList *head1, criList *head2);  /**连接两循环链表的函数的声明**/void print_L(criList*);void print_hyphen(int);int main(void){    criList *head = NULL;    criList *rnode = NULL;    head = createNullList();    head->next = head;    rnode = head;    if(head == NULL){        printf("链表初始化失败!\n");        exit(1);    }    printf("链表初始化成功!\n");    int end = 0;    int ope;    while(!end){        print_hyphen(15); printf("\n");        printf("请输入指令来执行操作\n");        print_hyphen(15); printf("\n");        printf("1、判断循环链表是否为空\n2、在链表尾部插入新结点\n3、连接两个单循环练链表\n4、退出\n");        print_hyphen(15); printf("\n");        printf("输入要使用的功能的序号: ");        scanf("%d", &ope);        switch(ope){            case 1:                if(isNullList(head))       /**判断是否链表是否为空的函数的调用(Y-1,N-0)**/                    printf("链表为空!\n");                else                    printf("链表不为空!\n");                break;            case 2:{                int insnum;                printf("请输入要插入到链尾的数据: ");                scanf("%d", &insnum);                if(insertNode(&rnode, insnum))                    printf("插入成功!\n");                else                    printf("插入失败!\n");                print_L(head);                break;            }            case 3:{                criList *headAnother = NULL;                criList *rnodeAnother;                headAnother = createNullList();                headAnother->next = headAnother;                rnodeAnother = headAnother;                if(headAnother == NULL){                    printf("另一链表初始化失败!\n");                    exit(1);                }                printf("另一链表初始化成功!\n");                printf("请输入新链表的元素的个数:");                int anonum,iano;                scanf("%d", &anonum);                printf("请输入各结点的数据(用空格隔开):\n");                while(anonum--){                    scanf("%d", &iano);                    insertNode(&rnodeAnother, iano);                }                printf("新建循环链表为:\n");                print_L(headAnother);                printf("将两表合并为:\n");                unionList(rnode, rnodeAnother);                print_L(head);                break;            }            case 4:                printf("再见!\n");                end = 1;                break;            default:                printf("无此序号,请重新输入!\n");        }    }    return 0;}criList* createNullList()         /**创建空链表的函数的定义**/{    criList* head = NULL;    head=(criList*)malloc(sizeof(criList));    if(head!=NULL){        head->next=head;        printf("Has create null list success!\n");    }    else        printf("Out of space!\n");    return head;}int isNullList(criList *head)      /**判断是否链表是否为空的函数的定义(Y-1,N-0)**/{    return head->next == head;}int insertNode(criList **pprnode, int n)    /**在链尾插入结点的函数的定义**/{    criList *pnew = (criList*)malloc(sizeof(criList));    if(pnew == NULL){        printf("Out of space!\n");        return 0;    }    pnew->data = n;    pnew->next = (*pprnode)->next;    (*pprnode)->next = pnew;    *pprnode = pnew;    return 1;}int unionList(criList *r1, criList *r2){    criList *p;    p = r1->next;    r1->next = r2->next->next;    free(r2->next);    r2->next = p;}void print_L(criList *head){    printf("\n当前链表中的数据为:\n");    criList *p = head->next;    while(p != head){        printf("%d ", p->data);        p = p->next;    }    printf("\n");}void print_hyphen(int n){    while(n--)        printf("-");}

还有一种是不设头结点的方法,只有一个尾指针

#include <stdio.h>#include <stdlib.h>typedef struct Node{    int data;    struct Node *next;}LinkQNode;void insertNode(LinkQNode**, int);void exNode(LinkQNode**);int main(void){    char ch;    int i,j,k;    int data;    LinkQNode *rnode = NULL;    LinkQNode *p;    while(scanf(" %c", &ch) && ch != 'Q'){        switch(ch){            case 'E':                /*在循环链表尾部插入一个结点*/                scanf("%d", &data);                insertNode(&rnode, data);                break;            case 'D':                /*在循环链表头部删除一个结点*/                exNode(&rnode);                break;            case 'P':                /*显示循环链表的所有结点,若为空则输出None*/                if(rnode == NULL){                    printf("None\n");                    break;                }                p = rnode->next;                while(p != rnode){                    printf("%d ", p->data);                    p = p->next;                }                printf("%d\n", p->data);                break;        }    }    return 0;}void insertNode(LinkQNode **pprnode, int n){    LinkQNode *pnew = (LinkQNode*)malloc(sizeof(LinkQNode));    pnew->data = n;    if(*pprnode == NULL){        *pprnode = pnew;        pnew->next = pnew;    }    pnew->next = (*pprnode)->next;    (*pprnode)->next = pnew;    *pprnode = pnew;}void exNode(LinkQNode **pprnode){    if((*pprnode)->next == *pprnode){        free(*pprnode);        *pprnode = NULL;    }    else{        LinkQNode *p;        p = (*pprnode)->next;        (*pprnode)->next = (*pprnode)->next->next;        free(p);    }}

其实我觉得这和循环队列很像

原创粉丝点击