• 一步一步学数据结构之1--1(循环链表)


            今天记录下循环链表,其实循环链表也就是将单链表中最后一个数据元素的next指针指向第一个元素。

            这里有一个概念需要说明下:

                    游标:在循环链表中可以定义一个“当前”指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素

            如图

        

            这里介绍静态链表的常用操作:

                             l 创建循环链表

                             l 销毁循环链表

                             l 清空循环链表

                             l 获取表长度

                             l 把node插入pos位置

                             l 获取pos位置的元素

                             l 删除pos位置的元素

                             l 删除表中与node相同的元素(删除第一个匹配成功的)

                             l 重置游标

                             l 返回游标所指向的结点

                             l 游标后移

                 

            代码总分为三个文件:

                    CircleList.h : 放置功能函数的声明,以及表的声明,表结点的定义 

                    CircleList.c : 放置功能函数的定义,以及表的定义

                    Main.c    : 主函数,使用功能函数完成各种需求,不过一般用作测试

           整体结构图为:

           这里详细说下插入操作和删除操作:

     

                  插入操作:

                         如图

                        

                         插入元素方法:

                                判断表和插入位置是否合法

                                由表头开始通过next域移动pos次后,当前元素的next域为要插入的位置

                                将新元素插入(和单链表插入方法相同)

                                表长度加1

                                判断是否为头插(就是头结点和首元素中间插入)

                                如果是头插的话,把尾结点的next域指向第一个元素(也就是头节点所指向的首元素)

                                如果之前表为空表,则游标指向插入的结点

      

                删除操作:

                       如图

                       

                       删除元素方法:

                              判断表和插入位置是否合法

                              由表头开始通过next域移动pos次后,当前元素的next指向的元素为要删除的元素

                              删除元素(和单链表删除元素相同)

                              表长度减1

                              判断是否删除的为首元素

                              如果删除的是首元素的话,把表尾结点的next域指向首元素

                              如果删除后表为空,则重置头结点的next域和游标

                              如果删除的结点正好游标也指向它,则游标后移

       

    OK! 上代码:

    CircleList.h

    #ifndef _CIRCLELIST_H_
    #define _CIRCLELIST_H_
    
    typedef void CircleList;
    typedef struct _tag_CircleListNode CircleListNode;
    
    struct _tag_CircleListNode
    {
    	CircleListNode* next;
    };
    
    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
    


    CircleList.c

    #include <stdio.h>
    #include <malloc.h>
    #include "CircleList.h"
    
    typedef struct _tag_CircleList
    {
    	CircleListNode header;
    	CircleListNode* slider;
    	int length;
    }TCircleList;
    
    CircleList* CircleList_Create()
    {
    	TCircleList* sList = (TCircleList*)malloc(sizeof(TCircleList));
    	
    	if(NULL != sList)
    	{
    		sList->header.next = NULL;
    		sList->slider = NULL;
    		sList->length = 0;
    	}
    	
    	return sList;
    }
    
    void CircleList_Destroy(CircleList* list)
    {
    	free(list);
    }
    
    void CircleList_Clear(CircleList* list)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	if(NULL != sList)
    	{
    		sList->header.next = NULL;
    		sList->slider = NULL;
    		sList->length = 0;
    	}
    }
    
    int CircleList_Length(CircleList* list)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	int ret = -1;
    	
    	if(NULL != sList)
    	{
    		ret = sList->length;
    	}
    	
    	return ret;
    }
    
    int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	int ret = (NULL!=sList)&&(NULL!=node)&&(0<=pos);
    	
    	int i = 0;
    	
    	if(ret)
    	{
    		CircleListNode* current = (CircleListNode*)sList;
    		
    		for(i=0; (i<pos)&&(current->next!=NULL); i++)
    		{
    			current = current->next;
    		}
    		
    		node->next = current->next;
    		current->next = node;
    		
    		if(0 == sList->length)
    		{
    			sList->slider = node;
    		}
    		
    		sList->length++;
    		
    		if(current == (CircleListNode*)sList)
    		{
    			CircleListNode* last = CircleList_Get(sList, sList->length-1);
    			
    			last->next = current->next;
    		}
    	}
    	
    	return ret;
    }
    
    CircleListNode* CircleList_Get(CircleList* list, int pos)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	CircleListNode* ret = NULL;
    	
    	int i = 0;
    	
    	if((NULL != sList)&&(0 < sList->length))
    	{
    		CircleListNode* current = (CircleListNode*)sList;
    		
    		for(i=0; i<pos; i++)
    		{
    			current = current->next;	
    		}
    		
    		ret = current->next;
    	}
    	
    	return ret;
    }
    
    CircleListNode* CircleList_Delete(CircleList* list, int pos)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	CircleListNode* ret = NULL;
    	
    	int i = 0;
    	
    	if((NULL != sList)&&(0 <= pos)&&(0 < sList->length))
    	{
    		CircleListNode* current = (CircleListNode*)sList;
    		CircleListNode* last = NULL;
    		
    		for(i=0; i<pos; i++)
    		{
    			current = current->next;
    		}
    		
    		ret = current->next;
    		current->next = ret->next;
    		
    		sList->length--;
    		
    		if(current == (CircleListNode*)sList)
    		{
    			last = (CircleListNode*)CircleList_Get(sList, sList->length-1);
    		}
    		
    		if(NULL != last)
    		{
    			sList->header.next = ret->next;
    			last->next = ret->next;
    		}
    		
    		if(ret == sList->slider)
    		{
    			sList->slider = ret->next;
    		}
    		
    		if(0 == sList->length)
    		{
    			sList->slider = NULL;
    			sList->header.next = NULL;
    		}
    	}
    	
    	return ret;
    }
    
    CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	CircleListNode* ret = NULL;
    	
    	int i = 0;
    	
    	if((NULL != sList)&&(NULL != node))
    	{
    		CircleListNode* current = (CircleListNode*)sList;
    		
    		for(i=0; i<sList->length; i++)
    		{
    			if(node == current->next)
    			{
    				ret = current->next;
    				break;
    			}
    			
    			current = current->next;
    		}
    		
    		if(NULL != ret)
    		{
    			CircleList_Delete(sList, i);
    		}
    	}
    	
    	return ret;
    }
    
    CircleListNode* CircleList_Reset(CircleList* list)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	CircleListNode* ret = NULL;
    	
    	if(NULL != sList)
    	{
    		sList->slider = sList->header.next;
    		ret = sList->slider;
    	}
    	
    	return ret;
    }
    
    CircleListNode* CircleList_Current(CircleList* list)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	CircleListNode* ret = NULL;
    	
    	if(NULL != sList)
    	{
    		ret = sList->slider;
    	}
    	
    	return ret;
    }
    
    CircleListNode* CircleList_Next(CircleList* list)
    {
    	TCircleList* sList = (TCircleList*)list;
    	
    	CircleListNode* ret = NULL;
    	
    	if(NULL != sList)
    	{
    		ret = sList->slider;
    		sList->slider = ret->next;
    	}
    	
    	return ret;
    }
    


    Main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "CircleList.h"
    
    typedef struct _tag_Value
    {
    	CircleListNode header;
    	int v;
    }Value;
    
    int main(void)
    {
    	int i = 0;
    	
    	CircleList* list = CircleList_Create();
    	
    	Value v1,v2,v3,v4,v5,v6,v7,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));
    	CircleList_Insert(list, (CircleListNode*)&v5, 5);
    	
    	CircleList_Delete(list, 0);
    	
    	for(i=0; i<2*CircleList_Length(list); i++)
    	{
    		Value* p = (Value*)CircleList_Get(list, i);
    		
    		printf("%d ", p->v);
    	}
    	printf("
    ");
    	
    	while(CircleList_Length(list) > 0)
    	{
    		Value* p = (Value*)CircleList_Delete(list, 0);
    		
    		printf("%d ", p->v);
    	}
    	printf("
    ");
    	
    	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));
    	CircleList_Insert(list, (CircleListNode*)&v5, CircleList_Length(list));
    	CircleList_Insert(list, (CircleListNode*)&v6, CircleList_Length(list));
    	CircleList_Insert(list, (CircleListNode*)&v7, CircleList_Length(list));
    	CircleList_Insert(list, (CircleListNode*)&v8, CircleList_Length(list));
    	
    	for(i=0; i<CircleList_Length(list); i++)
    	{
    		Value* p = (Value*)CircleList_Next(list);
    		
    		printf("%d ", p->v);
    	}
    	printf("
    ");
    	
    	CircleList_Reset(list);
    	
    	while(CircleList_Length(list) > 0)
    	{
    		Value* pV = NULL;
    		
    		for(i=1; i<3; i++)
    		{
    			CircleList_Next(list);
    		}
    		
    		pV = (Value*)CircleList_Current(list);
    		printf("%d
    ", pV->v);
    		
    		CircleList_DeleteNode(list, (CircleListNode*)pV);
    	}
    	
    	CircleList_Destroy(list);
    	
    	return 0;
    }
    


  • 相关阅读:
    jquery将日期转换成指定格式的字符串
    jquery双日历日期选择器bootstrap-daterangepicker日历插件
    JAVA实体类不要使用基本类型,基本类型包含byte、int、short、long、float、double、char、boolean
    S04_CH01_搭建工程移植LINUX/测试EMMC/VGA
    S03_CH13_ZYNQ A9 TCP UART双核AMP例程
    S03_CH12_基于UDP的QSPI Flash bin文件网络烧写
    S03_CH11_基于TCP的QSPI Flash bin文件网络烧写
    S03_CH10_DMA_4_Video_Stitch视频拼接系统
    S03_CH09_DMA_4_Video_Switch视频切换系统
    S03_CH08_DMA_LWIP以太网传输
  • 原文地址:https://www.cnblogs.com/riskyer/p/3231072.html
Copyright © 2020-2023  润新知