循环单链表的创建及插入-头插法和尾插法

什么是循环链表?

循环链表是另一种形式的链式存储结构,它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

循环链表的操作

1.初始化
2.头插法创建链表
3.尾插法创建链表
4.打印链表中的所有元素
5.其他的操作通普通单链表相同,这里不在赘述。参考文章:单链表基本操作

初始化链表

在初始化链表这里需要注意区分与普通单链表的差别。
普通单链表初始时把头结点的下一个结点指向NULL。
循环单链表初始化时把头结点的下一个结点指向了头结点本身。

/*初始化链表*/
int InitList_L(LinkList &L){
    L = (LinkList)malloc(sizeof(LNode));
    L->next = L;  //循环链表空表 头结点的下一个结点指向头结点本身 
    return 0; 
}

头插法创建链表

/*头插法创建结点*/
int CreateList_Head_L(LinkList &L,int n){
    for(int i=n;i>0;i--){
        LinkList newNode = (LinkList)malloc(sizeof(LNode));  //创建一个新结点 
        printf("请输入第%d个元素的值:",n-i+1);
        scanf("%d",&newNode->data);
        newNode->next = L->next;
        L->next = newNode;
    }
    return 0;
}

尾插法创建链表

/*尾插法*/
int CreateList_Rear_L(LinkList &L,int n) {
    LinkList p = L;
    while(p->next != L){  //寻找到最后一个结点 
        p = p->next;
    } 
    for(int i=0;i<n;i++){
        LinkList newNode = (LinkList)malloc(sizeof(LNode)); //创建一个新结点
        printf("请输入第%d个元素的值:",i+1);
        scanf("%d",&newNode->data);
        newNode->next = p->next;
        p->next = newNode;  
        p = p->next;
    }
    return 0;
}

打印链表中的元素

注意:判断什么时候循环完整个链表
此处两个指针来实现,一个指向头结点,一个指向当前的循环的结点。通过,两个指针是否相同来,来判断是都循环完成。

/*打印链表中元素*/
int PrintList(LinkList L) {
    LinkList p = L; 
    int i = 1;
    while(p->next != L){    
        p = p->next;
        printf("第%d个元素为:%d\n",i,p->data);
        i++;
    }    
    return 0;
}

完整代码

#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{
    int data;
    struct LNode * next;
}LNode,*LinkList; 

/*初始化链表*/
int InitList_L(LinkList &L){
    L = (LinkList)malloc(sizeof(LNode));
    L->next = L;  //循环链表空表 头结点的下一个结点指向头结点本身 
    return 0; 
} 

/*头插法创建结点*/
int CreateList_Head_L(LinkList &L,int n){
    for(int i=n;i>0;i--){
        LinkList newNode = (LinkList)malloc(sizeof(LNode));  //创建一个新结点 
        printf("请输入第%d个元素的值:",n-i+1);
        scanf("%d",&newNode->data);
        newNode->next = L->next;
        L->next = newNode;
    }
    return 0;
} 

/*尾插法*/
int CreateList_Rear_L(LinkList &L,int n) {
    LinkList p = L;
    while(p->next != L){  //寻找到最后一个结点 
        p = p->next;
    } 
    for(int i=0;i<n;i++){
        LinkList newNode = (LinkList)malloc(sizeof(LNode)); //创建一个新结点
        printf("请输入第%d个元素的值:",i+1);
        scanf("%d",&newNode->data);
        newNode->next = p->next;
        p->next = newNode;  
        p = p->next;
    }
    return 0;
}

/*打印链表中元素*/
int PrintList(LinkList L) {
    LinkList p = L; 
    int i = 1;
    while(p->next != L){    
        p = p->next;
        printf("第%d个元素为:%d\n",i,p->data);
        i++;
    }    
    return 0;
}
main(){
    LinkList L;
    int initStatus;
    int headStatus;
    int rearStatus; 
    //初始化话循环单链表 
    initStatus = InitList_L(L);
    if(initStatus==0){
        printf("链表初始化成功\n");
        printf("===============\n");
    }else{
        printf("链表初始化失败\n");
    }
    //头插法插入元素 
    headStatus = CreateList_Head_L(L,3); 
    if(headStatus==0){
        printf("头插法插入成功\n");
    }else{
        printf("头插法插入失败\n");
    }
    //打印链表中所有元素 
    PrintList(L);

    //尾插法插入元素
    rearStatus = CreateList_Rear_L(L,3);
    if(rearStatus==0){
        printf("尾插法插入成功\n");
    }else{
        printf("尾插法插入失败\n");
    }

    //打印链表中所有元素 
    PrintList(L);
}

运行结果

头插法插入的元素与输入的元素顺序相反,尾插法插入的元素顺序与插入的顺序相同。file

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
A: 头插法创建单链表的步骤如下: 1. 新建一个头结点,其指针域为空。 2. 依次读入数据,新建一个结点,并将其插入链表的头部。 代码如下: ``` #include <stdio.h> #include <stdlib.h> typedef struct ListNode { int val; struct ListNode *next; } ListNode; ListNode* createList() { ListNode *head = (ListNode*)malloc(sizeof(ListNode)); head->next = NULL; // 初始化头结点 int x; while (scanf("%d", &x) != EOF) { ListNode *newNode = (ListNode*)malloc(sizeof(ListNode)); newNode->val = x; newNode->next = head->next; head->next = newNode; } return head; } int main() { ListNode *head = createList(); head = head->next; // 链表头结点包含无用信息,需要去掉 while (head != NULL) { printf("%d ", head->val); head = head->next; } return 0; } ``` 尾插法创建单链表的步骤如下: 1. 新建一个头结点,其指针域为空。 2. 定义一个指针p指向头结点。 3. 依次读入数据,每读入一个数据新建一个结点,并将其插入链表的尾部。插入完成后,将p指向新建的结点。 代码如下: ``` ListNode* createList() { ListNode *head = (ListNode*)malloc(sizeof(ListNode)); head->next = NULL; // 初始化头结点 ListNode *p = head; // 初始指向头结点 int x; while (scanf("%d", &x) != EOF) { ListNode *newNode = (ListNode*)malloc(sizeof(ListNode)); newNode->val = x; newNode->next = NULL; // 将新结点的指针域设为空 // 将新结点插入链表尾部 p->next = newNode; p = p->next; // p指向新结点 } return head; } ``` 其中,scanf("%d", &x) != EOF 表示当未到达文件结束符时循环读入整数。在Windows命令行下, 文件结束符可以通过按 Ctrl+Z 或 F6 来输入。在Linux系统下,文件结束符可以通过按 Ctrl+D 来输入。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小陈没烦恼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值