链表
来源:互联网 发布:增加一列的sql语句 编辑:程序博客网 时间:2024/06/06 12:25
LinkList.h
#ifndef _LINKLIST_H_#define _LINKLIST_H_typedef void LinkList;//数据封装typedef struct _tag_LinkListNode LinkListNode;struct _tag_LinkListNode{ LinkListNode* next;};LinkList* LinkList_Create();void LinkList_Destroy(LinkList* list);void LinkList_Clear(LinkList* list);int LinkList_Length(LinkList* list);int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);LinkListNode* LinkList_Get(LinkList* list, int pos);LinkListNode* LinkList_Delete(LinkList* list, int pos);#endif
关于数据封装
typedef void LinkList;//一个假封装typedef struct _tag_LinkList{ LinkListNode header; int length;} TLinkList;//真封装
定义数据的时候用假封装,就比如LinkList* list = LinkList_Create();
定义了一个链表,如果我直接list->length = 3;来修改数据就破坏了这个链表,list这个指针应该只能被处理链表的函数来修改这样才是安全的。而这里list是void*,大家都知道void*不能当左值,因为void不知道是什么类型的,所以LinkList* list = LinkList_Create();
就会报错
LinkList.c
#include <stdio.h>#include <malloc.h>#include "LinkList.h"//定义链表的数据类型typedef struct _tag_LinkList{ LinkListNode header; int length;} TLinkList;//开辟一条链表LinkList* LinkList_Create() // O(1){ TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList)); if( ret != NULL ) { ret->length = 0; ret->header.next = NULL; } return ret;}//释放一条链表void LinkList_Destroy(LinkList* list) // O(1){ free(list);}//把链表数据清空void LinkList_Clear(LinkList* list) // O(1){ TLinkList* sList = (TLinkList*)list; if( sList != NULL ) { sList->length = 0; sList->header.next = NULL; }}//获取链表的长度int LinkList_Length(LinkList* list) // O(1){ TLinkList* sList = (TLinkList*)list; int ret = -1; if( sList != NULL ) { ret = sList->length; } return ret;}//链表中插入元素int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; int ret = (sList != NULL) && (pos >= 0) && (node != NULL); int i = 0; if( ret ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; (i<pos) && (current->next != NULL); i++)//错误1:没有检查是否到了链表末尾 { current = current->next; } //错误2:写成node->next = current->next;,node是指向节点的指针,node->next才是指向下一个元素的指针 node->next = current->next; current->next = node; sList->length++;//错误3:没有考虑到长度 } return ret;}//获取链表中的元素LinkListNode* LinkList_Get(LinkList* list, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; } return ret;}//删除链表中的元素LinkListNode* LinkList_Delete(LinkList* list, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; current->next = ret->next; //曾经写成current = ret->next; sList->length--;//错误++:再次没有减去数量 } return ret;}
main.c
#include <stdio.h>#include <stdlib.h>#include "LinkList.h"struct Value{ LinkListNode header; int v;};int main(int argc, char *argv[]) { int i = 0; LinkList* list = LinkList_Create(); struct Value v1; struct Value v2; struct Value v3; struct Value v4; struct Value v5; v1.v = 1; v2.v = 2; v3.v = 3; v4.v = 4; v5.v = 5; //强制类型转换LinkListNode*)&v1,并没有改变原来的结构体大小,只是指针类型变化了一下而已 LinkList_Insert(list, (LinkListNode*)&v1, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v2, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v3, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v4, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v5, LinkList_Length(list)); for(i=0; i<LinkList_Length(list); i++) {//强制类型转换LinkListNode*)&v1,并没有改变原来的结构体大小,只是指针类型变化了一下而已 struct Value* pv = (struct Value*)LinkList_Get(list, i); printf("%d\n", pv->v); } while( LinkList_Length(list) > 0 ) { struct Value* pv = (struct Value*)LinkList_Delete(list, 0); printf("%d\n", pv->v); } LinkList_Destroy(list); return 0;}
0 0