(C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
来源:互联网 发布:2016淘宝客api接口 编辑:程序博客网 时间:2024/05/18 12:31
昨天写了单向链表的代码,今天上午把单向循环链表的程序给敲完了。链表的相关操作一样的,包含链表的创建、判断链表是否为空、计算链表长度、向链表中插入节点、从链表中删除节点、删除整个链表释放内存。如果单向链表理解了,那单向循环链表也就不难了。
单向循环链表如下图所示:
看图可以知道,单向循环链表和单向链表差不多,只不过是最后的尾节点指向的不是空,而是指向头节点。理解这一点很重要,因为这是我们写程序的关键。下面我们上代码:
SqCcLinkList.h 头文件——定义了节点结构体,以及相关操作的函数声明。
- #ifndef ONE_WAY_CIRCULAR_LINK_LIST_H
- #define ONE_WAY_CIRCULAR_LINK_LIST_H
- typedef struct Node
- {
- int data;
- struct Node *pNext;
- }NODE, *pNODE;
- //创建单向循环链表
- pNODE CreateSgCcLinkList(void);
- //打印链表
- void TraverseSgCcLinkList(pNODE pHead);
- //判断链表是否为空
- int IsEmptySgCcLinkList(pNODE pHead);
- //计算链表的长度
- int GetLengthSgCcLinkList(pNODE pHead);
- //向链表中插入节点
- int InsertEleSgCcLinkList(pNODE pHead, int pos, int data);
- //从链表中删除节点
- int DeleteEleSgCcLinkList(pNODE pHead, int pos);
- //删除整个链表,释放内存
- void FreeMemory(pNODE *ppHead);
- #endif
(1)这部分是创建链表,和单向链表一样,一开始也是创建了一个头节点,初始化时,头结点的指针指向自己(这是和单向链表不一样的地方)。在写程序时,主要体现在下面的一行代码:
- p_new->pNext = pHead; //这里一定是pHead,因为最后一个节点总是指着头节点
- #include <stdio.h>
- #include <stdlib.h>
- #include "SgCcLinkLIst.h"
- //创建单向循环链表
- pNODE CreateSgCcLinkList(void)
- {
- int i, length = 0, data = 0;
- pNODE pTail = NULL, p_new = NULL;
- pNODE pHead = (pNODE)malloc(sizeof(NODE));
- if (NULL == pHead)
- {
- printf("内存分配失败!\n");
- exit(EXIT_FAILURE);
- }
- pHead->data = 0;
- pHead->pNext = pHead;
- pTail = pHead;
- printf("请输入要创建链表的长度:");
- scanf("%d", &length);
- for (i=1; i<length+1; i++)
- {
- p_new = (pNODE)malloc(sizeof(NODE));
- if (NULL == p_new)
- {
- printf("内存分配失败!\n");
- exit(EXIT_FAILURE);
- }
- printf("请输入第%d个节点的元素值:", i);
- scanf("%d", &data);
- p_new->data = data;
- p_new->pNext = pHead; //这里一定是pHead,因为最后一个节点总是指着头节点
- pTail->pNext = p_new;
- pTail = p_new;
- }
- return pHead;
- }
- //打印链表
- void TraverseSgCcLinkList(pNODE pHead)
- {
- pNODE pt = pHead->pNext;
- printf("链表打印如:");
- while (pt != pHead)
- {
- printf("%d ", pt->data);
- pt = pt->pNext;
- }
- putchar('\n');
- }
- //判断链表是否为空
- int IsEmptySgCcLinkList(pNODE pHead)
- {
- if (pHead->pNext == pHead)
- return 1;
- else
- return 0;
- }
- //计算链表长度
- int GetLengthSgCcLinkList(pNODE pHead)
- {
- int length = 0;
- pNODE pt = pHead->pNext;
- while (pt != pHead)
- {
- length++;
- pt = pt->pNext;
- }
- return length;
- }
(3)这部分是链表的插入和删除操作,和单向链表一样。
- //向链表中插入节点
- int InsertEleSgCcLinkList(pNODE pHead, int pos, int data)
- {
- pNODE p_new = NULL;
- if (pos > 0 && pos < GetLengthSgCcLinkList(pHead) + 2)
- {
- p_new = (pNODE)malloc(sizeof(NODE));
- if (NULL == <span style="font-family: Arial, Helvetica, sans-serif;">p_new </span><span style="font-family: Arial, Helvetica, sans-serif;">)</span>
- {
- printf("内存分配失败!\n");
- exit(EXIT_FAILURE);
- }
- while (1)
- {
- pos--;
- if (0 == pos)
- break;
- pHead = pHead->pNext;
- }
- p_new->data = data;
- p_new->pNext = pHead->pNext;
- pHead->pNext = p_new;
- return 1;
- }
- else
- return 0;
- }
- <span style="font-family: Arial, Helvetica, sans-serif;">//从链表中删除节点</span>
- int DeleteEleSgCcLinkList(pNODE pHead, int pos)
- {
- pNODE pt = NULL;
- if (pos > 0 && pos < GetLengthSgCcLinkList(pHead) + 1)
- {
- while (1)
- {
- pos--;
- if (0 == pos)
- break;
- pHead = pHead->pNext;
- }
- pt = pHead->pNext->pNext;
- free(pHead->pNext);
- pHead->pNext = pt;
- return 1;
- }
- else
- return 0;
- }
- //删除整个链表,释放内存
- void FreeMemory(pNODE *ppHead)
- {
- pNODE pt = NULL;
- while (*ppHead != NULL)
- {
- if (*ppHead == (*ppHead)->pNext) //如果只有头节点一个
- {
- free(*ppHead);
- *ppHead = NULL;
- }
- else //如果不止头节点一个
- {
- pt = (*ppHead)->pNext->pNext;
- free((*ppHead)->pNext);
- (*ppHead)->pNext = pt;
- }
- }
- }
main.cpp测试程序源文件——这个程序通过一些简单的交互用来测试各个函数是否实现了各自的功能。
- #include <stdio.h>
- #include <stdlib.h>
- #include "SgCcLinkList.h"
- int main(void)
- {
- int flag = 0, length = 0;
- int position = 0, value = 0;
- pNODE head = NULL;
- head = CreateSgCcLinkList();
- flag = IsEmptySgCcLinkList(head);
- if (flag)
- printf("单向循环链表为空!\n");
- else
- {
- length = GetLengthSgCcLinkList(head);
- printf("单向循环链表的长度为:%d\n", length);
- TraverseSgCcLinkList(head);
- }
- printf("请输入要插入节点的位置和元素值(两个数用空格隔开):");
- scanf("%d %d", &position, &value);
- flag = InsertEleSgCcLinkList(head, position, value);
- if (flag)
- {
- printf("插入节点成功!\n");
- TraverseSgCcLinkList(head);
- }
- else
- printf("插入节点失败!\n");
- flag = IsEmptySgCcLinkList(head);
- if (flag)
- printf("单向循环链表为空,不能进行删除操作!\n");
- else
- {
- printf("请输入要删除节点的位置:");
- scanf("%d", &position);
- flag = DeleteEleSgCcLinkList(head, position);
- if (flag)
- {
- printf("删除节点成功!\n");
- TraverseSgCcLinkList(head);
- }
- else
- printf("删除节点失败!\n");
- }
- FreeMemory(&head);
- if (NULL == head)
- printf("已成功删除单向循环链表,释放内存完成!\n");
- else
- printf("删除单向循环链表失败,释放内存未完成!\n");
- return 0;
- }
下一站是双向链表。加油吧!
0 0
- (C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(一)——实现单向链表创建、插入、删除等简单操作(包含个人理解说明及注释,新手跟着写代码)
- (C语言版)链表(一)——实现单向链表创建、插入、删除等简单操作(包含个人理解说明及注释,新手跟着写代码)
- (C语言版)链表(一)——实现单向链表创建、插入、删除等简单操作(包含个人理解说明及注释,新手跟着写代码)
- (C++版)链表(二)——实现单项循环链表创建、插入、删除等操作
- (C++版)链表(二)——实现单项循环链表创建、插入、删除等操作
- (C++版)链表(四)——实现双向循环链表创建、插入、删除等简单操作
- (C++版)链表(四)——实现双向循环链表创建、插入、删除等简单操作
- (C++版)链表(一)——实现单向链表创建、插入、删除等相关操作
- (C++版)链表(一)——实现单向链表创建、插入、删除等相关操作
- get_article_info
- hdu1045---Fire Net
- (C语言版)链表(一)——实现单向链表创建、插入、删除等简单操作(包含个人理解说明及注释,新手跟着写代码)
- Hadoop性能调优
- codeforces 514E Darth Vader and Tree (dp+快速幂)
- (C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- zoj 2158 && poj 1718 Truck History
- USACO 1.3 Wormholes 虫洞
- C++ STL 算法:查找算法(2) search_n
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- zoj 1586 QS Network
- 【c++模板笔记二】类模板的介绍以及使用方法
- 轻松搭建hadoop-1.2.1伪分布