Linux-C学习笔记--单链表的“浮云”操作
2013-11-10 12:17
344 查看
链表在C语言项目中很常见,学号链表,先从单链表开始,通常在学习阶段的单链表实现是基于某种数据类型或结构量身定做的操作方法,这种方法,没有通用性,在实际项目开发中,段不可取。于是乎,学习一种“浮云”般对单链表的操作是非常重要的。我们研究各个数据结点的数据,就会发现,无论它是什么类型,都有一个共同的特点,就是,他们都是存储在内存中的,它们拥有各子唯一的内存地址,于是乎,我们使用单链表的每个结点存储目标数据的地址,就可以抽象出一种通用的单链表操作方法,具体的操作方法,如下,此代码支持任何数据类型的单链表操作:
/**********************************************************************************************/
file : LinkList.h
/*******************************************************************************************************/
file : LinkList.c
/**********************************************************************************************/
file : LinkList.h
#ifndef _LINKLIST_H_ #define _LINKLIST_H_ typedef void LinkList; typedef void LinkListNode; extern LinkList* LinkList_Create(); extern void LinkList_Destroy(LinkList* list); extern void LinkList_Clear(LinkList* list); extern int LinkList_Length(LinkList* list); extern int LinkList_Insert(LinkList* list, LinkListNode* node, int pos); extern LinkListNode* LinkList_Get(LinkList* list, int pos); extern LinkListNode* LinkList_Delete(LinkList* list, int pos); extern void LinkList_Reverse(LinkList* list); #endif
/*******************************************************************************************************/
file : LinkList.c
#include <stdio.h> #include <malloc.h> #include "LinkList.h" typedef struct _tag_TLinkListNode TLinkListNode; struct _tag_TLinkListNode { unsigned int addr; TLinkListNode* next; }; typedef struct _tag_TLinkList { int length; TLinkListNode* header; }TLinkList; LinkList* LinkList_Create() { TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList)); if(ret != NULL) { ret->length = 0; ret->header = NULL; } return (LinkList*)ret; } void LinkList_Destroy(LinkList* list) { LinkList_Clear(list); free(list); list = NULL; } void LinkList_Clear(LinkList* list) { TLinkList* sList = (TLinkList*)list; if(sList != NULL) { while(sList->header != NULL) { TLinkListNode* pList = sList->header; sList->header = pList->next; free(pList); sList->length--; } } } /************************************************************************ * 获取单链表长度 * 返回-1表示获取失败 * 返回非负数既是单链表当前长度 ************************************************************************/ int LinkList_Length(LinkList* list) { int ret = -1; TLinkList* sList = (TLinkList*)list; if(sList != NULL) { ret = sList->length; } return ret; } /************************************************************************ * 插入结点 * 插入成功返回真 * 插入失败返回假 ************************************************************************/ int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) { int i = 0; TLinkList* sList = (TLinkList*)list; int ret = (sList != NULL) && (pos >= 0) && (node != NULL); if(ret) { TLinkListNode* pNew = (TLinkListNode*)malloc(sizeof(TLinkListNode)); if(pNew != NULL) { pNew->addr = (unsigned int)node; if(pos == 0 || sList->header == NULL) { pNew->next = sList->header; sList->header = pNew; } else { TLinkListNode* current = sList->header; for(i = 1; (i < pos) && (current->next != NULL); i++) { current = current->next; } pNew->next = current->next; current->next = pNew; } sList->length++; } else { ret = 0; } } return ret; } /************************************************************************ * 获取pos位置的结点 * 成功返回结点指针 * 失败返回空 ************************************************************************/ LinkListNode* LinkList_Get(LinkList* list, int pos) { int i = 0; TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { if(0 == pos) { ret = (LinkListNode*)(sList->header->addr); } else { TLinkListNode* current = sList->header; for(i=1; i<pos; i++) { current = current->next; } ret = (LinkListNode*)(current->next->addr); } } return ret; } /************************************************************************ * 删除pos位置的结点,并将删除的结点指针返回 * 成功返回结点指针 * 失败返回空 ************************************************************************/ LinkListNode* LinkList_Delete(LinkList* list, int pos) { TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { TLinkListNode* current = sList->header; if(0 == pos) { ret = (LinkListNode*)(sList->header->addr); sList->header = current->next; free(current); } else { for(i=0; i<pos-1; i++) { current = current->next; } ret = (LinkListNode*)(current->next->addr); current->next = current->next->next; free(current->next); } sList->length--; } return ret; } /************************************************************************ * 两种单链表逆序的操作 * 无返回值 ************************************************************************/ #if 1 /************************************************************************ // 修改结点指针 void LinkList_Reverse(LinkList* list) { TLinkList* sList = (TLinkList*)list; TLinkListNode* p1 = sList->header; if(LinkList_Length(list) == 2) { sList->header = p1->next; sList->header->next = p1; p1->next = NULL; } else if(LinkList_Length(list) > 2) { TLinkListNode* p2 = p1->next; sList->header = p2->next; p1->next = NULL; while(sList->header != NULL) { p2->next = p1; p1 = p2; p2 = sList->header; sList->header = sList->header->next; } sList->header = p2; p2->next = p1; } } #else // 利用单链表删除、插入操作,将原有单链表第0个数据结点取出来,存入临时单链表中的第0个数据
// 结点位置,直到原有单链表为空,再将临时单链表还给原有链表指针 void LinkList_Reverse(LinkList* list) { if(LinkList_Length(list) >= 2) { TLinkList* sList = (TLinkList*)list; LinkList* swapList = LinkList_Create(); while(sList->header != NULL) { LinkList_Insert(swapList, LinkList_Delete(list, 0), 0); } sList->header = ((TLinkList*)swapList)->header; sList->length = ((TLinkList*)swapList)->length; ((TLinkList*)swapList)->header = NULL; ((TLinkList*)swapList)->length = 0; LinkList_Destroy(swapList); } } #endif
相关文章推荐
- 通过unregister_filesystem()函数学习linux单链表操作
- c++学习笔记—单链表基本操作的实现
- Linux学习笔记:简单了解用户,对用户的简单操作
- linux学习笔记——认识docker及其操作命令
- Linux对文件内容基本操作(学习笔记七)
- Linux学习笔记六(Vim操作)
- opensuse linux操作维护学习笔记
- 学习Linux笔记(四)--文件操作
- Linux 基础目录 简单命令学习操作笔记
- Linux学习笔记--对文本的操作及正则表达式
- 【学习笔记】Linux基本操作(6)--- Vi文本编辑器
- Linux学习笔记一、初始操作,Ctrl+Alt+Fn,startx,exit,date,cal,bc,Ctrl+c,Ctrl+d,who,netstat -a,ps -aux,sync,init
- Linux学习笔记——常用文件操作命令
- 【学习笔记】Linux基本操作(5)--- Linux系统常用命令
- linux基础学习笔记——操作
- Linux程序设计-学习笔记-第三章文件操作
- Linux 学习笔记之 3 Linux图形操作环境
- linux系统管理操作指令学习笔记(三)管理好文件
- IPython(jupyter)简单介绍和基本交互操作 - 千月的python linux 系统管理指南学习笔记(5)
- Linux基础学习笔记之目录的相关操作