【链表】单链表——单循环链表

来源:互联网 发布:java程序员月薪 编辑:程序博客网 时间:2024/06/01 13:47

生气【链表】单链表——不带表头结点生气

得意【链表】单链表——带表头结点得意


  对于单链表,由于每个结点只存储了向后的指针,到了尾标志就停止了向后的操作,这样,当某一个结点找不到前驱结点了,也不能回去找。而我们现在要解决这个问题,就要利用循环链表。


  将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表。


  循环链表解决了一个很麻烦的问题:如何从一个结点出发,访问到链表的全部结点。


  为了使空链表与非空链表处理一致,我们通常设一个头结点,当然,并不是说循环链表一定要有头结点。


  其实循环链表和单链表的主要差异在于循环的判断条件上,之前是判断temp->next是否为空,现在是temp->next不等于头结点

 

一、设头结点

#include <stdio.h>#include <stdlib.h>/*=================定义链表数据结构=================*/struct node{    int num;    struct node *next;    //next存放下一个结点的地址};typedef struct node Node;typedef Node * Link;/*===================功能:设头结点返回:void===================*/void init_link(Link *head){    *head = (Link)malloc(sizeof(Node));    (*head)->next = *head;}int main(){    Link head;       //创建头指针    init_link(&head);  //设头结点     return 0;}

二、插入结点

1、头插

#include <stdio.h>#include <stdlib.h>/*=================定义链表数据结构=================*/struct node{    int num;    struct node *next;    //next存放下一个结点的地址};typedef struct node Node;typedef Node * Link;/*===================功能:设头结点返回:void===================*/void init_link(Link *head){    *head = (Link)malloc(sizeof(Node));    (*head)->next = *head;}/*=========================功能:从链表头部插入结点返回:void=========================*/void insert_head_node(Link newnode, Link *head){    newnode->next = (*head)->next;    (*head)->next = newnode;}/*=================功能:打印链表返回:void=================*/void print(Link head){    Link temp = head->next;    while (temp != head)    //遍历链表    {        printf("%d\n",temp->num);        temp = temp->next;    }}int main(){    Link head;       //创建头指针    Link newnode;    //创建新结点    init_link(&head);  //设头结点    int i;    for (i = 0; i < 10; i++)    {        newnode = (Link)malloc(sizeof(Node));  //逐一为结点分配空间        newnode->num = i + 1;                  //逐一为结点数据域赋值        insert_head_node(newnode,&head);       //头插    }        printf("头插后的链表为:\n");    print(head);                               //打印链表        return 0;}


运行结果:

头插后的链表为:10987654321


2、尾插

#include <stdio.h>#include <stdlib.h>/*=================定义链表数据结构=================*/struct node{    int num;    struct node *next;    //next存放下一个结点的地址};typedef struct node Node;typedef Node * Link;/*===================功能:设头结点返回:void===================*/void init_link(Link *head){    *head = (Link)malloc(sizeof(Node));    (*head)->next = *head;}/*=========================功能:从链表尾部插入结点返回:void=========================*/void insert_tail_node(Link newnode, Link *head){    Link temp = *head;    while (temp->next != *head)  //找到最后一个结点    {        temp = temp->next;    }    temp->next = newnode;       //插入结点    newnode->next = *head;}/*=================功能:打印链表返回:void=================*/void print(Link head){    Link temp = head->next;    while (temp != head)    //遍历链表    {        printf("%d\n",temp->num);        temp = temp->next;    }}int main(){    Link head;       //创建头指针    Link newnode;    //创建新结点    init_link(&head);  //设头结点    int i;    for (i = 0; i < 10; i++)    {        newnode = (Link)malloc(sizeof(Node));  //逐一为结点分配空间        newnode->num = i + 1;                  //逐一为结点数据域赋值        insert_tail_node(newnode,&head);       //尾插    }        printf("尾插后的链表为:\n");    print(head);                               //打印链表        return 0;}


运行结果:

尾插后的链表为:12345678910

3、从中间插入

#include <stdio.h>#include <stdlib.h>/*=================定义链表数据结构=================*/struct node{    int num;    struct node *next;    //next存放下一个结点的地址};typedef struct node Node;typedef Node * Link;/*===================功能:设头结点返回:void===================*/void init_link(Link *head){    *head = (Link)malloc(sizeof(Node));    (*head)->next = *head;}/*=========================功能:从链表尾部插入结点返回:void=========================*/void insert_tail_node(Link newnode, Link *head){    Link temp = *head;    while (temp->next != *head)  //找到最后一个结点    {        temp = temp->next;    }    temp->next = newnode;       //插入结点    newnode->next = *head;}/*=====================功能:从中间插入结点返回:是否成功执行=====================*/int insert_mid_node(Link newnode, Link head, int num){    Link temp = head->next;    while (temp != head)       //遍历链表    {        if (num == temp->num)  //判断是否为要插入的目标结点,是则插入         {            newnode->next = temp->next;            temp->next = newnode;            return 0;        }        temp = temp->next;    }    return -1;    //遍历整个链表也找不到目标结点,退出}/*=================功能:打印链表返回:void=================*/void print(Link head){    Link temp = head->next;    while (temp != head)    //遍历链表    {        printf("%d\n",temp->num);        temp = temp->next;    }}int main(){    Link head;       //创建头指针    Link newnode;    //创建新结点    init_link(&head);  //设头结点    int i;    for (i = 0; i < 10; i++)    {        newnode = (Link)malloc(sizeof(Node));  //逐一为结点分配空间        newnode->num = i + 1;                  //逐一为结点数据域赋值        insert_tail_node(newnode,&head);       //尾插    }        newnode = (Link)malloc(sizeof(Node));      //为新结点分配空间    newnode->num = 11;    insert_mid_node(newnode,head,5);           //在数据域为5的结点后插入结点    printf("从中间插入后的链表为:\n");    print(head);                               //打印链表        return 0;}


运行结果:

从中间插入后的链表为:1234511678910

三、删除结点

#include <stdio.h>#include <stdlib.h>/*=================定义链表数据结构=================*/struct node{    int num;    struct node *next;    //next存放下一个结点的地址};typedef struct node Node;typedef Node * Link;/*===================功能:设头结点返回:void===================*/void init_link(Link *head){    *head = (Link)malloc(sizeof(Node));    (*head)->next = *head;}/*=========================功能:从链表尾部插入结点返回:void=========================*/void insert_tail_node(Link newnode, Link *head){    Link temp = *head;    while (temp->next != *head)  //找到最后一个结点    {        temp = temp->next;    }    temp->next = newnode;       //插入结点    newnode->next = *head;}/*===================功能:删除某个结点返回:是否成功===================*/int del_mid_node(Link *head, int num){    if (*head == (*head)->next)    //判断是否为空表,空表则退出    {        return -1;    }    Link temp = *head;    Link ptr = temp;            //ptr指向temp的结点    temp = temp->next;          //temp指向下一个结点,即ptr指向temp前面的结点    while (temp != *head)        //遍历链表    {        if (num == temp->num)   //判断是否是要删除的结点,是则删除        {            ptr->next = temp->next;            free(temp);            temp = NULL;            return 0;        }        ptr = temp;        temp = temp->next;    }    return -1;    //遍历整个链表也找不到目标结点,则退出}/*=================功能:打印链表返回:void=================*/void print(Link head){    Link temp = head->next;    while (temp != head)    //遍历链表    {        printf("%d\n",temp->num);        temp = temp->next;    }}int main(){    Link head;       //创建头指针    Link newnode;    //创建新结点    init_link(&head);  //设头结点    int i;    for (i = 0; i < 10; i++)    {        newnode = (Link)malloc(sizeof(Node));  //逐一为结点分配空间        newnode->num = i + 1;                  //逐一为结点数据域赋值        insert_tail_node(newnode,&head);       //尾插    }           del_mid_node(&head,5);                     //删除数据域为5的结点    printf("删除数据域为5的结点后的链表为:\n");    print(head);                               //打印链表        return 0;}

运行结果:

删除数据域为5的结点后的链表为:1234678910

四、逆序

#include <stdio.h>#include <stdlib.h>/*=================定义链表数据结构=================*/struct node{    int num;    struct node *next;    //next存放下一个结点的地址};typedef struct node Node;typedef Node * Link;/*===================功能:设头结点返回:void===================*/void init_link(Link *head){    *head = (Link)malloc(sizeof(Node));    (*head)->next = *head;}/*=========================功能:从链表尾部插入结点返回:void=========================*/void insert_tail_node(Link newnode, Link *head){    Link temp = *head;    while (temp->next != *head)  //找到最后一个结点    {        temp = temp->next;    }    temp->next = newnode;       //插入结点    newnode->next = *head;}/*===============功能:逆序链表返回:是否成功===============*/int reverse_link(Link *head){    /*判断是否只有一个头结点或除了头结点只有一个结点,是则退出*/    if (*head == (*head)->next || *head == (*head)->next->next)    {        return -1;    }    Link str = *head;    Link ptr = str->next;    Link temp = ptr->next;    while (*head != temp)    {        ptr->next = str;        str = ptr;        ptr = temp;        temp = temp->next;    }    ptr->next = str;    (*head)->next->next = *head;    (*head)->next = ptr;    return 0;}/*=================功能:打印链表返回:void=================*/void print(Link head){    Link temp = head->next;    while (temp != head)    //遍历链表    {        printf("%d\n",temp->num);        temp = temp->next;    }}int main(){    Link head;       //创建头指针    Link newnode;    //创建新结点    init_link(&head);  //设头结点    int i;    for (i = 0; i < 10; i++)    {        newnode = (Link)malloc(sizeof(Node));  //逐一为结点分配空间        newnode->num = i + 1;                  //逐一为结点数据域赋值        insert_tail_node(newnode,&head);       //尾插    }        reverse_link(&head);                       //逆序    printf("逆序后的链表为:\n");    print(head);                               //打印链表        return 0;}

运行结果:

逆序后的链表为:10987654321

1 0