循环链表(c语言)

目录

循环链表的概念

 循环链表与单链表的区别

循环链表的常用操作 

 循环列表的实现

建立新的结点

循环链表的定义

初始化循环链表

循环链表的插入

循环链表的删除

循环链表的查询

循环链表的输出

完整代码 

效果图 ​编辑

小结 

参考文献


 

循环链表的概念

循环链表是一种特殊的链表结构。它与普通链表不同的地方在于,最后一个节点指向第一个节点,形成了一个环。这也就意味着,在循环链表中,每个节点都有前驱节点和后继节点。循环链表既可以向前遍历,也可以向后遍历。

 循环链表与单链表的区别

循环单链表和单链表的区别就是,需要查找尾结点,然后将尾结点的next域指向头结点并形成一个循环,单链表直接指向NULL即可。

循环链表的常用操作 

  1. 头节点:循环链表第一个节点之前的节点,通常没有存储数据,主要作用是方便对循环链表的操作。

  2. 尾节点:循环链表最后一个节点,其next指针指向头节点。

  3. 插入元素:在指定位置插入新元素,需要修改前一个节点的next指针和新节点的next指针。

  4. 删除元素:删除指定位置的元素,需要修改前一个节点的next指针。

  5. 查找元素:从头节点开始遍历循环链表,直到找到目标元素或遍历完整个链表。

 循环列表的实现

  1. 建立新的结点
    typedef struct Node {
        int data;
        struct Node* next;
    } Node;.
    
  2. 循环链表的定义
    typedef struct CircularLinkedList {
        Node* head;
        Node* tail;
        int length;
    } CircularLinkedList;
  3. 初始化循环链表
    void init_circular_linked_list(CircularLinkedList* list) {
        list->head = NULL;
        list->tail = NULL;
        list->length = 0;
    }
  4. 循环链表的插入
    // 在头部插入节点
    void insert_at_start(CircularLinkedList* list, int data) {
        Node* new_node = (Node*)malloc(sizeof(Node));
        new_node->data = data;
        new_node->next = list->head;
        list->head = new_node;
        list->length++;
    }
    // 在任意i位置处插入元素x
    void insert_at_position(CircularLinkedList* list, int x, int i) {  
        Node* new_node = (Node*)malloc(sizeof(Node));  
        new_node->data = x;  
        new_node->next = NULL;  
      
        if (i == 0) { 
            new_node->next = list->head;  
            list->head = new_node;  
            if (list->tail == NULL) { 
                list->tail = new_node;  
            }  
        } else { 
            Node* temp = list->head;  
            int count = 0;  
            while (temp != NULL && count < i-1) {  
                temp = temp->next;  
                count++;  
            }  
            if (temp == NULL) {
                new_node->next = list->tail;  
                list->tail->next = new_node;  
                list->tail = new_node;  
            } else { 
                new_node->next = temp->next;  
                temp->next = new_node;  
            }  
        }  
        list->length++; 
    }
    // 在尾部插入节点
    void insert_at_end(CircularLinkedList* list, int data) {
        Node* new_node = (Node*)malloc(sizeof(Node));
        new_node->data = data;
        new_node->next = NULL;
    
        if (is_empty(list)) {
            list->head = new_node;
            list->tail = new_node;
            list->length++;
        } else {
            list->tail->next = new_node;
            list->tail = new_node;
            list->length++;
        }
    }
  5. 循环链表的删除
    //删除指定值得节点
    void delete_node(CircularLinkedList* list, int data) {
        Node* current = list->head;
        Node* previous = NULL;
        while (current != NULL && current->data != data) {
            previous = current;
            current = current->next;
        }
        if (current == NULL) { // 没有找到要删除的节点
            printf("Element not found.\n");
            return;
        }
        if (previous == NULL) { // 删除头节点
            list->head = current->next;
            if (list->length == 1) {
                list->tail = NULL;
            }
        } else { // 删除其他节点
            previous->next = current->next;
            if (list->length == 1) {
                list->tail = previous;
            }
        }
        free(current);
        list->length--;
    }
  6. 循环链表的查询
    // 查找指定值x所在的位置i
    int find_position(CircularLinkedList* list, int x) {
        Node* current = list->head;
        int position = 0;
        while (current != NULL) {
            if (current->data == x) {
                return position;
            }
            current = current->next;
            position++;
        }
        return -1; // 没有找到要查找的元素就让他在前移
    }
  7. 循环链表的输出
    void print_circular_linked_list(CircularLinkedList* list) {  
        Node* node = list->head;  
        int i;  
        for (i = 0; i < list->length; i++) {  
            printf("%d ", node->data);  
            node = node->next;  
            if (node == list->head) break; // 循环链表结束,退出循环  
        }  
        printf("\n");  
    }

完整代码 

#include <stdio.h>
#include <string.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node;

typedef struct CircularLinkedList {
    Node* head;
    Node* tail;
    int length;
} CircularLinkedList;

void init_circular_linked_list(CircularLinkedList* list) {
    list->head = NULL;
    list->tail = NULL;
    list->length = 0;
}

// 判断循环链表是否为空
int is_empty(CircularLinkedList* list) {
    return list->length == 0;
}


// 在头部插入节点
void insert_at_start(CircularLinkedList* list, int data) {
    Node* new_node = (Node*)malloc(sizeof(Node));
    new_node->data = data;
    new_node->next = list->head;
    list->head = new_node;
    list->length++;
}

// 在任意i位置处插入元素x
void insert_at_position(CircularLinkedList* list, int x, int i) {  
    Node* new_node = (Node*)malloc(sizeof(Node));  
    new_node->data = x;  
    new_node->next = NULL;  
  
    if (i == 0) { 
        new_node->next = list->head;  
        list->head = new_node;  
        if (list->tail == NULL) { 
            list->tail = new_node;  
        }  
    } else { 
        Node* temp = list->head;  
        int count = 0;  
        while (temp != NULL && count < i-1) {  
            temp = temp->next;  
            count++;  
        }  
        if (temp == NULL) {
            new_node->next = list->tail;  
            list->tail->next = new_node;  
            list->tail = new_node;  
        } else { 
            new_node->next = temp->next;  
            temp->next = new_node;  
        }  
    }  
    list->length++; 
}

// 在尾部插入节点
void insert_at_end(CircularLinkedList* list, int data) {
    Node* new_node = (Node*)malloc(sizeof(Node));
    new_node->data = data;
    new_node->next = NULL;

    if (is_empty(list)) {
        list->head = new_node;
        list->tail = new_node;
        list->length++;
    } else {
        list->tail->next = new_node;
        list->tail = new_node;
        list->length++;
    }
}

// 返回循环链表长度
int get_length(CircularLinkedList* list) {
    return list->length;
}
//删除指定值得节点
void delete_node(CircularLinkedList* list, int data) {
    Node* current = list->head;
    Node* previous = NULL;
    while (current != NULL && current->data != data) {
        previous = current;
        current = current->next;
    }
    if (current == NULL) { // 没有找到要删除的节点
        printf("Element not found.\n");
        return;
    }
    if (previous == NULL) { // 删除头节点
        list->head = current->next;
        if (list->length == 1) {
            list->tail = NULL;
        }
    } else { // 删除其他节点
        previous->next = current->next;
        if (list->length == 1) {
            list->tail = previous;
        }
    }
    free(current);
    list->length--;
}

// 查找指定值x所在的位置i
int find_position(CircularLinkedList* list, int x) {
    Node* current = list->head;
    int position = 0;
    while (current != NULL) {
        if (current->data == x) {
            return position;
        }
        current = current->next;
        position++;
    }
    return -1; // 没有找到要查找的元素就让他在前移
}

// 打印循环链表
void print_circular_linked_list(CircularLinkedList* list) {  
    Node* node = list->head;  
    int i;  
    for (i = 0; i < list->length; i++) {  
        printf("%d ", node->data);  
        node = node->next;  
        if (node == list->head) break; // 循环链表结束,退出循环  
    }  
    printf("\n");  
}
 
int main() {
	char welcome[] = "\n\
    ★╭------╮☆☆☆☆☆☆╭------╮\n\
    ★╰╮八方来财╭╯◢ █ ◣◢ █ ◣╰╮期末高分╭╯\n\
    ★╭╯╰---╯╰╮██自  由██╭╯╰---╯╰╮\n\
    ★║◢ █ ◣◢ █ ◣║◥ █快乐█ ◤║◢ █ ◣◢ █ ◣║\n\
    ★║██████████║ ◥ ██ ◤ ║██████████║ \n\
    ★║◥ █真心█ ◤║         ║◥ █祝福█ ◤║\n\
    ★║ ◥ ██ ◤ ║☆ ☆ ☆ ☆ ☆║ ◥ ██ ◤ ║\n\
    ★║  ◥ ◤  ║☆ 事事如意☆ ║ ◥ ◤ ║\n\
         \\   ☆ 祝我 . 也祝你!☆\n\n";
	int i = 0; 
	int m = 0; 
	int n = 0;
    for(i=0;i<strlen(welcome);i++)
	{
		printf("%c",welcome[i]);
		for(m=0;m<10000;m++)
			for(n=0;n<1000;n++)
			{
				;
			}
	}
	printf("\n\n\n");
	
    int data; // 用于存储用户输入的节点数据  
    int position;//插入的位置 
    int option; // 用于存储用户选择的操作选项  
	CircularLinkedList list;
    init_circular_linked_list(&list); //初始化 
    do {  
        printf("-----------顺序表演示程序----------\n");
        printf("1. 初始化顺序表\n");
        printf("2. 头插法\n");
        printf("3. 中间插入法\n");
        printf("4. 尾插法\n");
        printf("5. 查询元素位置\n");
        printf("6. 删除元素\n");
        printf("7. 循环链表的长度\n");
        printf("8. 打印循环链表\n");
        printf("9. 帮助\n"); 
        printf("0. 退出\n");
        printf("请输入您要进行的操作(1~9,0退出):");
        scanf("%d", &option);  
  
        switch (option) { 
			case 1:
				printf("初始化成功!\n");
				break;
            case 2:
				printf("请输入要添加的数值\n");  
                scanf("%d", &data);  
                insert_at_start(&list, data);
                printf("添加成功!\n");
                break;
            case 3:
            	printf("请输入需要插入的位置和要添加的数值\n");  
                scanf("%d %d",&data,&position);  
                insert_at_position(&list,data,position); 
                printf("添加成功!\n");
                break;

            case 4: // 添加节点到循环链表  
                printf("请输入要添加的数值\n");  
                scanf("%d", &data);  
                insert_at_end(&list, data);
                printf("添加成功!\n");
                break;
			case 5: // 查找节点  
                printf("请输入要查询的数值\n");  
                scanf("%d", &data);  
                int position = find_position(&list, data); 
				printf("元素: %d 发现在位置: %d.\n",data, find_position(&list, data)); 
				break;
            
            case 6: // 删除节点  
                printf("请输入要删除的位置\n");  
                scanf("%d", &position);  
                delete_node(&list,position);
                printf("删除成功!\n");
                break;  
              
            case 7: // 获取循环链表的长度  
                printf("循环链表的长度为: %d\n", get_length(&list));  
                break;  
            case 8:
				print_circular_linked_list(&list);// 打印循环链表 
				break;
			case 9:
				printf(" 本程序为循环链表的演示程序,由王路平编写!\n");
				break;
            case 0: // 退出程序  
                printf("Exiting program...\n");  
                break;  
            default: // 处理无效选项  
                printf("Invalid option entered. Please enter a valid option.\n");  
                break;  
        }  
    } while (option != 0); // 当用户选择退出程序时,结束循环  
  
    return 0; 
}

效果图 

小结 

循环列表的概念:循环链表是一种特殊的链表结构。它与普通链表不同的地方在于,最后一个节点指向第一个节点,形成了一个环。这也就意味着,在循环链表中,每个节点都有前驱节点和后继节点。循环链表既可以向前遍历,也可以向后遍历。循环列表的优点就是从链尾到链头比较方便。比如需要处理的数据具有环形结构特点时,用循环列表就非常合适。虽然单链表也可以实现,但是循环链表的代码要简洁的多。

参考文献

第二章——单链表和循环单链表_循环链表和单链表的区别-CSDN博客

C语言数据结构——循环链表_c 实现循环链表_管不住嘴的小吃货的博客-CSDN博客

百度,书本等

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值