线性存储
#ifndef __MY_SEQLIST_H__
#define __MY_SEQLIST_H__
#define ERR_BASE 0
#define ERR_PARAM ERR_BASE -1;
typedef void SeqList;
typedef void SeqListNode;
SeqList* SeqList_Create(int capacity);
void SeqList_Destroy(SeqList* list);
void SeqList_Clear(SeqList* list);
int SeqList_Length(SeqList* list);
int SeqList_Capacity(SeqList* list);
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);
SeqListNode* SeqList_Get(SeqList* list, int pos);
SeqListNode* SeqList_Delete(SeqList* list, int pos);
#endif //__MY_SEQLIST_H__
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "seqlist.h"
// //里面应该开辟一块数组 用来保存插入节点的指针 数组的大小不一定 动态数组的首地址int * node;\ capacity length;
typedef struct _tag_SeqList
{
int length;
int capacity;
unsigned int *node;
}TSeqList;
//创建链表
SeqList * SeqList_Create(int capacity)
{
TSeqList *ret = NULL;
ret = (TSeqList*)malloc(sizeof(TSeqList));
if (ret==NULL)
{
return NULL;
}
ret->capacity = capacity;
ret->node = (unsigned int *)malloc(sizeof(unsigned int*)*capacity);
if (ret->node==NULL)
{
return NULL;
}
ret->length = 0;
return ret;
//定义成void 就是不让别人知道我是什么结构的。也没有必要让别人知道
/*typedef void SeqList; 重命名
typedef void SeqListNode;*/
}
//在业界还有人这么做
//SeqList * SeqList_Create(int capacity)
//{
// TSeqList * ret = NULL;
// ret = (TSeqList *)malloc(sizeof(TSeqList)+sizeof(unsigned int *)*capacity);
// if (ret==NULL)
// {
// return NULL;
// }
// ret->capacity = capacity;
// ret->node = (unsigned int *)(ret +1);
// ret->length = 0;
// return ret;
//}
void SeqList_Destory(SeqList *list)
{
if (list=NULL)
{
return;
}
free(list);
return;
}
void SeqList_Clear(SeqList* list)
{
//让线性表回到原始状态
TSeqList *tlist = list;
if (list==NULL)
{
return;
}
tlist->length = 0;
return;
}
int SeqList_Length(SeqList* list)
{
TSeqList *tlist = list;
if (list == NULL)
{
return -1;
}
return tlist->length;
}
int SeqList_Capacity(SeqList* list)
{
TSeqList *tlist = list;
if (list == NULL)
{
return -1;
}
return tlist->capacity;
}
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
int i = 0;
TSeqList *tlist = list;
if (list==NULL|| node==NULL)
{
return -1;
}
if (pos<0||pos>=tlist->capacity)
{
return -2;
}
//如果已满
if (tlist->length>=tlist->capacity)
{
return -3;
}
//容错
if (pos>tlist->length)
{
pos = tlist->length;
}
//插入算法
//从插入的位置后移元素
//注意length 能表现出现在数组的最后元素位置
//最后元素的下标为 node[i-1];
for (i = tlist->length; i > pos;i--)
{
tlist->node[i] = tlist->node[i-1];
}
//在pos 位置插入元素
tlist->node[pos] = (unsigned int)node;
}
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
int i;
TSeqList *tlist = list;
if (list == NULL || pos>=tlist->length)
{
return NULL;
}
return (SeqListNode*)tlist->node[pos];
}
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
int i = 0;
TSeqList *tlist = list;
SeqListNode* ret = NULL;
if (tlist==NULL||pos<0||pos>=tlist->length)
{
return NULL;
}
//缓存要删除的节点
ret = (SeqListNode*)tlist->node[pos];
//对链表进行移动
for (i = pos + 1; i < tlist->length;i++)
{
tlist->node[i - 1] = tlist->node[i];
}
tlist->length--;
return ret;//返回值为被删除的元素,NULL 表示删除失败
}
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "seqlist.h"
typedef struct _Teacher
{
char name[64];
int age;
int buf;
}Teacher;
void main()
{
int ret = 0, i = 0;
Teacher t1, t2, t3;
SeqList* list = NULL;
t1.age = 10;
t2.age = 20;
t3.age = 30;
list = SeqList_Create(10);
//业务模型是把地址传入动态库中
//里面应该开辟一块数组 用来保存插入节点的指针 数组的大小不一定 动态数组的首地址int * node;\ capacity length;
//仔细思考:业务数据 和 链表算法(底层库)是如何分离的。。。。。。
//业务数据结点的管理(内存的生命周期)甩给了上层应用(业务模型)
ret = SeqList_Insert(list, (SeqListNode*)&t1, 0);
ret = SeqList_Insert(list, (SeqListNode*)&t2, 0);
ret = SeqList_Insert(list, (SeqListNode*)&t3, 0);
//上层应用程序分配好内存,地址放到链表库,链表库对地址进行管理,释放不释放生命周期,应该是上层说的算,底层库不应该控制节点的生命周期
//业务数据节点的管理(内存的生命周期)甩给了上层应用(业务模型)
//循环遍历
for (i = 0; i<SeqList_Length(list); i++)
{
Teacher *tmp = (Teacher *)SeqList_Get(list, i);
printf("age:%d \n", tmp->age);
}
//循环删除
for (i = 0; i<SeqList_Length(list); i++)
{
SeqList_Delete(list, 0);
}
SeqList_Destroy(list);
system("pause");
}
线性表链式存储
#include <stdlib.h>
#include <stdio.h>
#include "string.h"
#include "linklist.h"
typedef struct _Teacher
{
LinkListNode *node;//前面4个字节 是不是指针都可以
char name[64];
int age;
} Teacher;
void main()
{
int ret = 0;
int i = 0;
LinkList *list = NULL;
Teacher t1, t2, t3, t4, t5;
t1.age = 10;
t2.age = 20;
t3.age = 30;
t4.age = 40;
t5.age = 50;
//把Teacher业务节点加入链表里面
list= LinkList_Create();
LinkList_Insert(list,(LinkListNode*)(&t1),LinkList_Length(list));
LinkList_Insert(list, (LinkListNode*)(&t2), LinkList_Length(list));
for (i = 0; i < LinkList_Length(list); i++)
{
Teacher* tmp = (Teacher*)LinkList_Get(list,i);
if (tmp!=NULL)
{
printf("%d",tmp->age);
}
}
printf("\n");
for (i = 0; i < 2; i++)
{
Teacher * tmp = (Teacher*)LinkList_Delete(list,0);
if (tmp!=NULL)
{
printf("%d",tmp->age);
}
}
LinkList_Destroy(list);
system("pause");
}
#ifndef __MY_LINK_H__
#define __MY_LINK_H__
typedef void LinkList;
typedef struct _tag_LinkListNode
{
struct _tag_LinkListNode* next;
} LinkListNode;
LinkList* LinkList_Create();
void LinkList_Destroy(LinkList* list);
void LinkList_Clear(LinkList* list);
int LinkList_Length(LinkList* list);
int LinkList_Capacity(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 //__MY_LINK_H__
#include "linklist.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct _tag_LinkList
{
LinkListNode header;
int length;
}TLinkList;
LinkList* LinkList_Create()
{
TLinkList *tList = (TLinkList*)malloc(sizeof(TLinkList));
if (tList==NULL)
{
return NULL;
}
tList->header.next = NULL;
tList->length = 0;
return tList;
}
void LinkList_Destroy(LinkList* list)
{
if (list!=NULL)
{
free(list);
}
return ;
}
void LinkList_Clear(LinkList* list)
{
TLinkList *tList = list;
if (tList==NULL)
{
return;
}
tList->length = 0;
tList->header.next = NULL;
return ;
}
int LinkList_Length(LinkList* list)
{
TLinkList *tList = list;
if (tList == NULL)
{
return -1;
}
return tList->length;
}
int LinkList_Capacity(LinkList* list)
{
return 0;
}
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
int i = 0;
TLinkList *tList = list;
LinkListNode *current = NULL;
if (tList == NULL||node==NULL||pos<0)
{
return 0;
}
current = &tList->header;
//current = (LinkListNode*)list;//首地址,这样也可以
for (i = 0; (i < pos) && current->next != NULL;i++)
{
current = current->next;
}
node->next = current->next;
current->next = node;
tList->length++;
return 0;
}
LinkListNode* LinkList_Get(LinkList* list, int pos)
{
int i = 0;
TLinkList *tList = list;
LinkListNode *current = NULL;
LinkListNode * ret = NULL;
if (list==NULL||pos<0||pos>=tList->length)
{
return NULL;
}
current = &tList->header;
for (i = 0; i < pos;i++)
{
current = current->next;
}
ret = current->next;
return ret;
}
LinkListNode* LinkList_Delete(LinkList* list, int pos)
{
int i = 0;
TLinkList *tList = list;
LinkListNode *current = NULL;
LinkListNode * ret = NULL;
if (list == NULL || pos<0 || pos >= tList->length)
{
return NULL;
}
current = &tList->header;
for (i = 0; i < pos;i++)
{
current = current->next;
}
ret = current->next;
current->next = ret->next;
tList->length--;
return ret;
}
线性存储
优点:
无需要为线性表中的逻辑关系增加额外的空间
可以快速的获取表中合法位置的元素
缺点:
插入和删除操作需要移动大量元素
当线性表长度变化大时难以确定存储空间的容量
链式存储
有点
无需要一次性定制链表的容量
插入和删除无需移动数据元素
缺点
数据元素必须保存后继元素的位置信息
获取指定数据的元素操作需要顺序访问之前的元素