循环链表的实现与操作(C语言实现)

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

循环链表的操作

1,循环链表的新操作

2, 获取当前游标指向的数据元素

3, 将游标重置指向链表中的第一个数据元素

4,将游标移动指向到链表中的下一个数据元素

5,直接指定删除链表中的某个数据元素

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

CircleListNode* CircleList_Reset(CircleList* list);

CircleListNode* CircleList_Current(CircleList* list);

CircleListNode* CircleList_Next(CircleList* list);

头文件:

#ifndef _CIRCLE_H_
#define _CIRCLE_H_
//采用数据封装的方式,防止在主函数修改其中的属性值(有点点像面向对象中的私有属性)
typedef void CircleList;
typedef struct CircleListNode   //声明指针域
{
	CircleListNode * next;
}CircleListNode;

CircleList * CircleList_Create();

void CircleList_DesTroy(CircleList * list);

void CircleList_Clear(CircleList* list);

int CircleList_Length(CircleList* list);

int CircleList_Insert(CircleList* list, CircleListNode* node, int pos);

CircleListNode* CircleList_Get(CircleList* list, int pos);

CircleListNode* CircleList_Delete(CircleList* list, int pos);

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

CircleListNode* CircleList_Reset(CircleList* list);

CircleListNode* CircleList_Current(CircleList* list);

CircleListNode* CircleList_Next(CircleList* list) ;

#endif 

源文件:

// 循环链表.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <malloc.h>
#include <stdlib.h>
#include "CircleList.h"

typedef struct   //定义头结点
{
   CircleListNode header;
   CircleListNode* sLider;  //游标
   int len;
}TCircleList;

struct Value        //定义数据结构体类型
{

    CircleListNode header;  //指针域
    int v;                //数据域
};

int _tmain(int argc, _TCHAR* argv[])
{	

     int i = 0;
    CircleList* list = CircleList_Create();

    struct Value v1;
    struct Value v2;
    struct Value v3;
    struct Value v4;
    struct Value v5;
    struct Value v6;
    struct Value v7;
    struct Value v8;

    v1.v = 1;
    v2.v = 2;
    v3.v = 3;
    v4.v = 4;
    v5.v = 5;
    v6.v = 6;
    v7.v = 7;
    v8.v = 8;

    CircleList_Insert(list, (CircleListNode*)&v1, CircleList_Length(list));
    CircleList_Insert(list, (CircleListNode*)&v2, CircleList_Length(list));
    CircleList_Insert(list, (CircleListNode*)&v3, CircleList_Length(list));
    CircleList_Insert(list, (CircleListNode*)&v4, CircleList_Length(list));
	//插入到 5 的位置,前面的顺序为 1->2->3->4
	//                      下标: 0  1  2  3
	//                             4  5 ...
	//故而插入到 5 的位置时  打印的结果应为 :  1,5,2,3,4,后面的结果也验证了其正确性
    CircleList_Insert(list, (CircleListNode*)&v5, 5);

    for(i=0; i<CircleList_Length(list); i++)
    {
        struct Value* pv = (struct Value*)CircleList_Get(list, i);

        printf("%d\n", pv->v);
    }

    while( CircleList_Length(list) > 0 )
    {
        struct Value* pv = (struct Value*)CircleList_Delete(list, 0);

        printf("删除了:%d\n", pv->v);
    }

    CircleList_DesTroy(list);

	system("pause");
	return 0;
}

//创建
CircleList * CircleList_Create()
{
	TCircleList* list = (TCircleList*)malloc(sizeof(TCircleList));
	if(NULL != list)
	{
		list->sLider = NULL;
		list->header.next = NULL;
		list->len = 0;

	}
	return list;
}

//销毁
void CircleList_DesTroy(CircleList * list)
{
	free(list);
}
//清空
void CircleList_Clear(CircleList* list)
{
	TCircleList * sList = (TCircleList*)list;
	if(NULL != sList)
	{
		sList->len = 0;
		sList->header.next = NULL;
		sList->sLider = NULL;
	}
}
//获得长度
int CircleList_Length(CircleList* list)
{
	TCircleList * sList = (TCircleList*)list;
	int len = -1;
	if(NULL != sList)
	{
		len = sList->len;
	}
	return len;
}
//插入
int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
{
	TCircleList * sList = (TCircleList*)list;
	int i = 0;
	int ret = 0;
	sList->len;
	if((NULL != sList) && (pos>=0) && (NULL != node))
	{
		CircleListNode * current = (CircleListNode*)sList;
		for ( i=0; i<pos && current->next != NULL; i++)
		{
			current = current->next;
		}

		node->next = current->next;
		current->next = node;
		if(sList->len == 0)
		{
			sList->sLider = node;
			node->next = node;
		}
		++(sList->len);
		ret = 1;

	}
   return ret;
}
//获得结点
CircleListNode* CircleList_Get(CircleList* list, int pos)
{
	TCircleList * sList = (TCircleList*)list;
	CircleListNode * resNode = NULL;
	int i = 0;
	if((NULL != sList) && (pos>=0))
	{
		CircleListNode * current = (CircleListNode*)sList;
		for( i=0; i<pos; i++)
		{
			//i=0时,current为头结点,current->next为真正的第一个结点
			current = current->next;
		}
		resNode = current->next;
	}
	return resNode;
}

//删除
CircleListNode* CircleList_Delete(CircleList* list, int pos)
{
	TCircleList * sList = (TCircleList*)list;
	int i = 0;
	CircleListNode * resnode = NULL;
	CircleListNode* first = sList->header.next;
	CircleListNode* last = (CircleListNode*)CircleList_Get(list,sList->len-1);
	if((NULL != sList) && (pos >= 0) && (pos < sList->len))
	{
		CircleListNode * current = (CircleListNode*)sList;
		for ( i=0; i<pos; i++)
		{
			//i=0时,current为头结点,current->next为真正的第一个结点
			current = current->next;
		}
		resnode = current->next;
		current->next = resnode->next;

		if(first == resnode)
		{
			sList->header.next = first->next;
			last->next = first->next;
		}
		if(sList->sLider == resnode)
		{
			sList->sLider = resnode->next;
		}
		if(sList->len == 0)
		{
			sList->header.next = NULL;
			sList->sLider = NULL;
		}
	}
	sList->len--;
	return resnode;
}

//根据结点来删除
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
{
	TCircleList * sList = (TCircleList*)list;
	CircleListNode* resnode = NULL;
	int i = 0;
	if(NULL != sList)
	{
		CircleListNode* current = (CircleListNode*)sList;
		for ( i=0; i<sList->len; i++)
		{
			if(node == current->next)
			{
				resnode = current->next;
				break;
			}
			current = current->next;
		}
		if(NULL != resnode)
		{
			CircleList_Delete(sList,i);
		}
	}
	return resnode;
}

//将游标重置回第一个元素
CircleListNode* CircleList_Reset(CircleList* list)
{
    TCircleList* sList = (TCircleList*)list;
    CircleListNode* ret = NULL;

    if( sList != NULL )
    {
		sList->sLider= sList->header.next;
        ret = sList->sLider;
    }

    return ret;
}

//获得当前游标下的结点
CircleListNode* CircleList_Current(CircleList* list)
{

    TCircleList* sList = (TCircleList*)list;
    CircleListNode* ret = NULL;
	sList->len;
	sList->header;
	sList->sLider;
    if( sList != NULL )
    {
		ret = sList->sLider;
    }

    return ret;
}

//将游标移到下一个结点并获得当前移动前的结点
CircleListNode* CircleList_Next(CircleList* list)
{
    TCircleList* sList = (TCircleList*)list;
    CircleListNode* ret = NULL;

	if( (sList != NULL) && (sList->sLider != NULL) )
    {
        ret = sList->sLider;
        sList->sLider = ret->next;
    }

    return ret;
}

运行结果:

1
5
2
3
4
删除了:1
删除了:5
删除了:2
删除了:3
删除了:4
请按任意键继续. . .

如有错误,望不吝指出。

循环链表的实现与操作(C语言实现)

时间: 2024-10-17 03:27:43

循环链表的实现与操作(C语言实现)的相关文章

双向链表的实现与操作(C语言实现)

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循环链表. 单链表的局限 1,单链表的结点都只有一个指向下一个结点的指针 2,单链表的数据元素无法直接访问其前驱元素 3,逆序访问单链表中的元素是极其耗时的操作 双向链表的操作 双向链表的新操作 1,获取当前游标指向的数据元素 2,将游标重置指向链表中的第一个数据元素 3,将游标移动指向到链表中的下一个数据

树的实现与操作(C语言实现)

首先来简单说下一些关于的基本概念. 树是一种非线性的数据结构 1,树是由 n(n>=0)个结点组成的有限集合 如果n = 0 ,称为空树 如果n > 0,则: 有一个特定的称之为根(root)的结点,它只有直接后继,但没有直接前驱 除了根以外的其他结点划分为:m(m>=0)个互不相交的有限集合,T0,T1,T2-Tn-1,每个集合又是一棵树,并且称之为根的子树 2,树中的概念: 树的结点包括一个数据及若干指向子树的分支 结点拥有的子树树称为结点的度 度为0的结点称为叶结点 度不为0的结点

栈的实现与操作(C语言实现)

栈的定义  1, 栈是一种特殊的线性表  2,栈仅能在线性表的一端进行操作  3,栈顶(Top): 同意操作的一端 同意操作的一端  4,栈底(Bottom): ,不同意操作的一端 不同意操作的一端 这里我做出了 栈的顺序实现 和 链式实现.分别例如以下: =========================================华丽丽的切割线========================================================== 栈的顺序实现: 首先

静态链表的实现与操作(C语言实现)

我们知道要实现单链表,必须要有指针,那么像Java这样没有指针的的语言就略显蛋疼了. 没关系,我们有静态链表,其本质就是用采用数组的方式实现单链表的功能. 头文件: #ifndef _StaticLinkList_H_ #define _StaticLinkList_H_ typedef void StaticLinkList; typedef void StaticLinkListNode; StaticLinkList * StaticLinkList_Create(int capacity

给定一个二进制数,要求循环移位,在原二进制数中操作(C语言)

int b = 0, c = 0;// b 输入的0~255之间的数 c 移动位数 printf("请输入一个整数和移动位数\n"); scanf("%d%d", &b, &c); unsigned char a = b; unsigned char left = 0;//存储左移之后的结果     unsigned char right = 0;//存储右移之后的结果     //循环移位 right = a >> c; left =

neo4j初次使用学习简单操作-cypher语言使用

Neo4j 使用cypher语言进行操作 Cypher语言是在学习Neo4j时用到数据库操作语言(DML),涵盖对图数据的增删改查  neo4j数据库简单除暴理解的概念: Neo4j中不存在表的概念,只有两类:节点(Node)和关联(Relation),可以简单理解为图里面的点和边.在数据查询中,节点一般用小括号(),关联用中括号[].当然也隐含路径的概念,是用节点和关联表示的,如:(a)-[r]->(b),表示一条从节点a经关联r到节点b的路径.  备份Neo4j的数据: 1)停掉数据库. 2

二叉树的实现与操作(C语言实现)

 二叉树的定义:     上一篇的树的通用表示法太过于复杂,由此这里采用了孩子兄弟表示法来构建二叉树. 孩子兄弟表示法: 每个结点包含一个数据指针和两个结点指针 --->数据指针:指向保存于树中的数据 --->孩子结点指针:指向第一个孩子 --->兄弟结点指针:指向第一个右兄弟 二叉树是由 n( n>=0 ) 个结点组成的有限集合,该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的.互不相交的二叉树组成. 特殊的二叉树: 定义1:满二叉树(Full Binary T

动态单链表的传统存储方式和10种常见操作-C语言实现

顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. 一般链表的存储方法 一组物理位置任意的存储单元来存放线性表的数据元素,当然物理位置可以连续,也可以不连续,或者离散的分配到内存中的任意位置上都是可以的.故链表的逻辑顺序和物理顺序不一定一样. 因为,链表的逻辑关系和物理关系没有必然联系,那么表示数据元素之间的逻辑映象就要使用指针,每一个存储数据元素

C#操作动态语言----Python

ususing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Scripting.Hosting;