数据结构base
相互之间存在一种或多种特定关系的数据元素的集合。
逻辑结构
集合,所有数据在同一个集合中,关系平等。
线性,数据和数据之间是一对一的关系
树, 一对多
图,多对多
物理结构(在内存当中的存储关系)
顺序存储,数据存放在连续的存储单位中。逻辑关系和物理关系一致
链式,数据存放的存储单位是随机或任意的,可以连续也可以不连续。
struct Per 数据元素
{
char name;//数据项(数据:变量,数据项:数据类型)
int age;
char phone;
}
struct Per list[100]; //数据对象(数据元素的集合)
数据的类型,ADT abstruct datatype(抽象数据类型)
是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。
原子类型,int,char,float
结构类型,sturct, union,
抽象数据类型, 数学模型 + 操作。
程序 = 数据 + 算法
算法,
是解决特定问题求解步骤的描述,计算机中表现为指令的有限序列,每条指令表示一个或多个操作。
算法的特征,
1,输入,输出特性,输入时可选的,输出时必须的。
2,有穷性,执行的步骤会自动结束,不能是死循环,并且每一步是在可以接受的时间内完成。
3,确定性,同一个输入,会得到唯一的输出。
4,可行性,每一个步骤都是可以实现的。
算法的设计,
1,正确性,
语法正确
合法的输入能得到合理的结果。
对非法的输入,给出满足要求的规格说明
对精心选择,甚至刁难的测试都能正常运行,结果正确
2,可读性,便于交流,阅读,理解
3,健壮性,输入非法数据,能进行相应的处理,而不是产生异常
4,高效,存储低,效率高
算法时间复杂度
也就是执行这个算法所花时间的度量
n 1 = O(n) O(1)
推到时间复杂度
1,用常数1 取代运行时间中的所有加法常数
2,在修改后的运行函数中,只保留最高阶项。
3,如果最高阶存在且不是1,则取除这个项相乘的常数。
O(1)<O(logn)<O(N)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
线性表(一对一)
线性表
零个或多个数据元素的有限序列
元素之间是有顺序了。如果存在多个元素,第一个元素无前驱,最有一个没有后继,其他的元素只有一个前驱和一个后继。
当线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,为空表。在非空的表中每个元素都有一个确定的位置,如果a1是第一个元素,那么an就是第n个元素。
顺序表seq_list
线性表的常规操作 ADT
顺序表c语言描述:
typedef struct person {
char name[32];
char sex;
int age;
int score;
}DATATYPE;//DATATYPE:通用数据类型
typedef int Datatype;
typedef struct list {
DATATYPE *head;
int tlen;//当前有效数据有几个
int clen;//容量有多大
}SeqList;
//都是用malloc开辟空间的
SeqList *CreateSeqList(int len);//创建
int DestroySeqList(SeqList *list);//销毁
int ShowSeqList(SeqList *list);//遍历
int InsertTailSeqList(SeqList *list, DATATYPE data);//尾插,追加
int IsFullSeqList(SeqList *list);//判断数组满了没有
int IsEmptySeqList(SeqList *list);//判断是否为空
int InsertPosSeqList(SeqList *list, DATATYPE data, int pos);//按位置插入
int FindSeqList(SeqList *list, char *name);//查找
int ModifySeqList(SeqList *list, char *old, DATATYPE new);//替换
int DeleteSeqList(SeqList *list, char *name);//删除其中一个
int ClearSeqList(SeqList *list);//清空表
内存泄露检测工具
sudo apt-get install valgrind
valgrind ./all
线性表顺序存储的优点,缺点
优点
1,无需为表中的逻辑关系增加额外的存储空间
2,可以快速随机访问元素O(1)
缺点
1,插入,删除元素需要移动元素o(n)
2,无法动态存储。
功能实现函数:
#include "seqlist.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
SeqList *CreateSeqList(int len)
{
SeqList* sl = malloc(sizeof(SeqList));
if(NULL == sl)
{
perror("CreateSeqList malloc");
return NULL;
}
sl->head = malloc(sizeof(DATATYPE)*len);
if(NULL == sl->head)
{
perror("CreateSeqList malloc2");
return NULL;
}
sl->clen = 0;
sl->tlen = len;
return sl;
}
int DestroySeqList(SeqList *list)
{
free(list->head);
free(list);
return 0;
}
int InsertTailSeqList(SeqList *list, DATATYPE *data)
{
if(IsFullSeqList(list))
{
printf("list is full\n");
return 1;
}
memcpy(&list->head[list->clen],data,sizeof(DATATYPE));
list->clen++;
return 0;
}
int IsFullSeqList(SeqList *list)
{
return list->clen == list->tlen;
}
int IsEmptySeqList(SeqList *list)
{
return 0 == list->clen;
}
int ShowSeqList(SeqList *list)
{
int i = 0 ;
int len = GetSizeSeqList(list);
for(i=0;i<len;i++)
{
printf("name:%s gender:%c age:%d score:%d\n",list->head[i].name
,list->head[i].gender,list->head[i].age,list->head[i].score);
}
return 0;
}
int GetSizeSeqList(SeqList *list)
{
return list->clen;
}
int FindSeqList(SeqList *list, char *name)
{
int i = 0 ;
int len = GetSizeSeqList(list);
for(i =0 ;i<len;i++)
{
if(0==strcmp(list->head[i].name,name))
{
return i;
}
}
return -1;
}
DATATYPE *GetItemSeqList(SeqList *list, int pos)
{
int len = GetSizeSeqList(list);
if(pos<0||pos>=len)
{
return NULL;
}
return &list->head[pos];
}
int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata)
{
int ret = FindSeqList(list,old);
if(-1 == ret)
{
return 1;
}
memcpy(&list->head[ret],newdata,sizeof(DATATYPE));
return 0;
}
int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos)
{
int len = GetSizeSeqList(list);
if(pos<0||pos>len)
{
return 1;
}
for(int i=list->clen;i!=pos ;i--)
{
list->head[i]= list->head[i-1];
}
memcpy(&list->head[pos],data,sizeof(DATATYPE));
list->clen++;
return 0;
}
int ClearSeqList(SeqList *list)
{
list->clen=0;
return 0;
}
int DeleteSeqList(SeqList *list, char *name)
{
return 0;
}
函数头:
#ifndef SEQLIST_H
#define SEQLIST_H
typedef struct person {
char name[32];
char gender;
int age;
int score;
}DATATYPE;
typedef struct list {
DATATYPE *head;
int tlen;
int clen;
}SeqList;
SeqList *CreateSeqList(int len);
int DestroySeqList(SeqList *list);
int ShowSeqList(SeqList *list);
int InsertTailSeqList(SeqList *list, DATATYPE *data);
int IsFullSeqList(SeqList *list);
int IsEmptySeqList(SeqList *list);
int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos);
int FindSeqList(SeqList *list, char *name);
int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata);
int DeleteSeqList(SeqList *list, char *name);
int ClearSeqList(SeqList *list);
int GetSizeSeqList(SeqList*list);
DATATYPE* GetItemSeqList(SeqList*list,int pos);
#endif
主函数,测试功能函数是否正确:
#include <stdio.h>
#include "seqlist.h"
int main()
{
DATATYPE data[]={
{"zhangsan",'m',20,80},
{"lisi",'f',21,82},
{"wangmazi",'f',22,70},
{"lao6",'f',30,70},
{"zhaosi",'f',30,50},
};
SeqList*sl= CreateSeqList(10);
InsertTailSeqList(sl,&data[0]);
InsertTailSeqList(sl,&data[1]);
InsertTailSeqList(sl,&data[2]);
ShowSeqList(sl);
printf("--------find----------\n");
char want_name[50]="li2si";
int ret = FindSeqList(sl,want_name);
if(-1 == ret)
{
printf("can't find %s\n",want_name);
}
else
{
DATATYPE* find_data = GetItemSeqList(sl,ret);
printf("name:%s score:%d\n",find_data->name,find_data->score);
}
printf("--------modify----------\n");
ModifySeqList(sl,"lisi",&data[3]);
ShowSeqList(sl);
printf("--------ins pos----------\n");
InsertPosSeqList(sl,&data[4],2);
ShowSeqList(sl);
DestroySeqList(sl);
printf("Hello World!\n");
return 0;
}
线性表的链式存储 单链表
解决顺序存储的缺点,插入和删除,动态存储问题。
特点:
,线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素,存储单元可以是连续的,也可以不连续。可以被存储在任意内存未被占用的位置上。
所以前面的顺序表只需要存储数据元素信息就可以了。在链式结构中还需要一个元素存储下一个元素的地址。
为了表示每个数据元素,ai与其直接后继数据元素ai+1之间的逻辑关系,对ai来说,除了存储其本身的信息外,还需要存一个指示器直接后续的信息。把存储元素信息的域叫数据域,把存储直接后继位置的域叫指针域。这两部分信息组成数据元素ai的存储映像,叫结点(Node);
单链表中,c语言的描述
typedef struct person {
char name[32];
char sex;
int age;
int score;
}DATATYPE;
typedef struct node {
DATATYPE data;
struct node *next,*prev;
}LinkNode;
typedef struct list {
LinkNode *head;
int tlen;
int clen;
}LinkList;
LinkList *CreateLinkList(int len);
int InsertHeadLinkList(LinkList *list, DATATYPE data);
int ShowLinkList(LinkList *list);
LinkNode *FindLinkList(LinkList *list, char *name);
int DeleteLinkList(LinkList *list, char *name);
int ReviseLinkList(LinkList *list, char *name, DATATYPE data);
int DestroyLinkList(LinkList *list);
int InsertTailLinkList(LinkList *list, DATATYPE data);
顺序表和链表 优缺点
存储方式:
顺序表是一段连续的存储单元
链表是逻辑结构连续物理结构(在内存中的表现形式)不连续
时间性能,
查找 顺序表O(1)
链表 O(n)
插入和删除
顺序表 O(n)
链表 O(1)
空间性能
顺序表 需要预先分配空间,大小固定
链表, 不需要预先分配,大小可变,动态分配
循环链表
简单的来说,就是将原来单链表中最有一个元素的next指针指向第一个元素或头结点,链表就成了一个环,头尾相连,就成了循环链表。circultlar linker list.
注意非空表,和空表。多数会加入头结点。
原来结束的条件是
p->next != NULL ------->>>>> p-next != Head
功能实现函数:
#include "link.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
SLinkList * CreateSLinkList()
{
SLinkList* sll = (SLinkList*) malloc(sizeof(SLinkList));
if(NULL == sll)
{
perror("CreateSLinkList malloc");
return NULL;
}
sll->head = NULL;
sll->clen = 0 ;
return sll;
}
int IsEmptySLinkList(SLinkList*sll)
{
return 0 == sll->clen ;
}
int InsertHeadSLinkList(SLinkList* sll,DATATYPE *data)
{
SLinkNode* newnode = (SLinkNode*)malloc(sizeof(SLinkNode));
if(NULL == sll)
{
perror("inserthead malloc");
return 1;
}
memcpy(&newnode->data ,data,sizeof(DATATYPE));
newnode->next = NULL;
if(IsEmptySLinkList(sll))
{
sll->head = newnode;
}
else
{
newnode->next = sll->head;
sll->head = newnode;
}
sll->clen++;
return 0;
}
int ShowSLinkList(SLinkList*sll)
{
SLinkNode* tmp = sll->head ;
while(tmp)
{
printf("name:%s score:%d\n",tmp->data.name ,tmp->data.score);
tmp= tmp->next ;//i++
}
return 0;
}
SLinkNode * FindSlinkList(SLinkList*sll,FUN fun,void* arg)
{
SLinkNode* tmp = sll->head;
int len = GetSizeSLinkList(sll);
int i = 0;
for(i=0;i<len;i++)
{
//if(0==strcmp(tmp->data.name,name))
if(fun(&tmp->data,arg))
{
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
int GetSizeSLinkList(SLinkList*sll)
{
return sll->clen;;
}
int ModifySlinkList(SLinkList*sll,FUN fun,void* arg,DATATYPE*newdata)
{
SLinkNode* tmp= FindSlinkList(sll,fun, arg);
if(NULL == tmp)
{
fprintf(stderr,"can find\n");
return 1;
}
else
{
memcpy(&tmp->data,newdata,sizeof(DATATYPE));
}
return 0;
}
int DeleteSLinkList(SLinkList*sll,FUN fun,void* arg)
{
//待删除节点的前一个指针
SLinkNode*prev = NULL;
SLinkNode*tmp = sll->head;
int len = GetSizeSLinkList(sll);
if(len == 1)
{
free(sll->head);
sll->head = NULL;
sll->clen = 0 ;
return 0;
}
//至少2个节点
while(1)
{
if(fun(&tmp->data,arg))
{
if(prev)
{
prev->next = tmp->next;
}
else
{
sll->head = tmp->next;
}
free(tmp);
sll->clen--;
return 0;
}
prev = tmp;
tmp = tmp->next;
if(NULL == tmp)
{
//删除失败
//return 1;
break;
}
}
return 1;
}
int DestroySLinkList(SLinkList *sll) {
SLinkNode *tmp = sll->head;
while (1) {
tmp = sll->head;
if (!tmp)
break;
sll->head = sll->head->next;
free(tmp);
}
free(sll);
return 0;
}
int InserTailSlinkList(SLinkList* sll,DATATYPE *data)
{
if(IsEmptySLinkList(sll))
{
return InsertHeadSLinkList(sll,data);
}
else
{
SLinkNode*tmp = sll->head;
while(tmp->next)
{
tmp = tmp->next;
}
SLinkNode* newnode = malloc(sizeof(SLinkNode));
if(NULL == newnode)
{
perror("insert tail malloc");
return 1;
}
memcpy(&newnode->data,data,sizeof(DATATYPE));
newnode->next = NULL;
tmp->next = newnode;
sll->clen++;
}
return 0;
}
int InserPosSlinkList(SLinkList* sll,DATATYPE *data,int pos)
{
int len = GetSizeSLinkList(sll);
if(pos<0 || pos > len)
{
return 1;
}
if(0 == pos)
{
return InsertHeadSLinkList(sll,data);
}
else if(pos == len)
{
return InserTailSlinkList(sll,data);
} else // mid
{
int i = 0;
SLinkNode *prev = sll->head;
for (i = 0; i < pos - 1; i++) {
prev = prev->next;
}
SLinkNode *newnode = malloc(sizeof(SLinkNode));
if (NULL == newnode) {
perror("insert pos malloc");
return 1;
}
memcpy(&newnode->data, data, sizeof(DATATYPE));
newnode->next = NULL;
newnode->next = prev->next;
prev->next = newnode;
}
sll->clen++;
return 0;
}
函数头:
#ifndef _LINK_H_
#define _LINK_H_
typedef struct person {
char name[32];
char sex;
int age;
int score;
}DATATYPE;
typedef struct node {
DATATYPE data;
struct node *next;
}SLinkNode;
typedef struct list {
SLinkNode *head;
int clen;
}SLinkList;
typedef int (*FUN)(DATATYPE*data,void *arg);
SLinkList * CreateSLinkList();
int InsertHeadSLinkList(SLinkList* sll,DATATYPE *data);
int IsEmptySLinkList(SLinkList*sll);
int ShowSLinkList(SLinkList*sll);
//SLinkNode * FindSlinkList(SLinkList*sll,char* name);
SLinkNode * FindSlinkList(SLinkList*sll,FUN fun,void* arg);
int GetSizeSLinkList(SLinkList*sll);
int ModifySlinkList(SLinkList*sll,FUN fun,void* arg,DATATYPE*newdata);
int DeleteSLinkList(SLinkList*sll,FUN fun,void* arg);
int DestroySLinkList(SLinkList*sll);
int InserTailSlinkList(SLinkList* sll,DATATYPE *data);
int InserPosSlinkList(SLinkList* sll,DATATYPE *data,int pos);
#endif
主函数,测试功能函数是否正确:
#include "link.h"
#include <stdio.h>
#include <string.h>
int findNodeByName(DATATYPE*data,void* arg)
{
return 0==strcmp(data->name,(char*)arg);
}
int findNodeByScore(DATATYPE*data,void* arg)
{
return data->score == *(int*)arg;;
}
int main(int argc, char *argv[])
{
DATATYPE data[]={
{"zhangsan",'m',20,80},
{"lisi",'f',21,82},
{"wangmazi",'f',22,70},
{"lao6",'f',30,70},
{"zhaosi",'f',30,50},
};
SLinkList * sll = CreateSLinkList();
InsertHeadSLinkList(sll,&data[0]);
InsertHeadSLinkList(sll,&data[1]);
InsertHeadSLinkList(sll,&data[2]);
ShowSLinkList(sll);
char want_name[50]="lisi";
int want_score=80;
//SLinkNode* tmp = FindSlinkList(sll, want_name);
//SLinkNode* tmp = FindSlinkList(sll, findNodeByName,want_name);
SLinkNode* tmp = FindSlinkList(sll, findNodeByScore,&want_score);
if(NULL == tmp)
{
printf("can't find %s\n",want_name);
}
else
{
printf("find it; name:%s score:%d\n",tmp->data.name,tmp->data.score);
}
printf("----------modify---------------\n");
ModifySlinkList(sll, findNodeByName, "lisi", &data[3]);
ShowSLinkList(sll);
/*
printf("----------del---------------\n");
DeleteSLinkList(sll,findNodeByName,"wangmazi");
ShowSLinkList(sll);
*/
printf("----------pos---------------\n");
InserPosSlinkList(sll,&data[4],3);
ShowSLinkList(sll);
DestroySLinkList(sll);
sll= NULL;
printf("hello world\n");
return 0;
}
双向链表:
功能实现函数:
#include "dlink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
LinkList *CreateLinkList()
{
LinkList*ll = (LinkList*)malloc(sizeof(LinkList));
if(NULL == ll)
{
perror("CreateLinkList malloc");
return NULL;
}
ll->head = NULL;
ll->clen = 0;
return ll;
}
int InsertHeadLinkList(LinkList *list, DATATYPE *data)
{
LinkNode* newnode = (LinkNode*)malloc(sizeof(LinkNode));
if(NULL == newnode)
{
perror("InsertHeadLinkList malloc");
return 1;
}
memcpy(&newnode->data,data,sizeof(DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
if(IsEmptyLinkList(list))
{
list->head = newnode;
}
else
{
newnode->next = list->head;
list->head->prev = newnode;
list->head = newnode;
}
list->clen++;
return 0;
}
int ShowLinkList(LinkList *list ,DIRECT dir)
{
int i=0;
int len =GetSizeLinkList(list);
LinkNode* tmp = list->head;
if(DIR_FORWARD == dir)
{
for(i = 0 ;i<len;i++)
{
printf("name:%s age:%d score:%d\n",tmp->data.name,tmp->data.age,tmp->data.score);
tmp=tmp->next;
}
}
else
{
while(tmp->next)
{
tmp=tmp->next;
}
while(tmp)
{
printf("name:%s age:%d score:%d\n",tmp->data.name,tmp->data.age,tmp->data.score);
tmp=tmp->prev;
}
}
return 0;
}
LinkNode *FindLinkList(LinkList *list, char *name)
{
int len = GetSizeLinkList(list);
int i = 0 ;
LinkNode*tmp = list->head;
for(i = 0 ;i<len;i++)
{
if(0==strcmp(tmp->data.name,name))
{
return tmp;
}
tmp=tmp->next;
}
return NULL;
}
int DeleteLinkList(LinkList *list, char *name)
{
LinkNode*tmp = FindLinkList(list,name);
if(NULL == tmp)
{
return 1;
}
if(tmp->next)
{
tmp->next->prev=tmp->prev;
}
if(tmp->prev)
{
tmp->prev->next = tmp->next;
}
else
{
list->head = tmp->next;
}
free(tmp);
list->clen--;
return 0;
}
int ModifyLinkList(LinkList *list, char *name, DATATYPE *data)
{
LinkNode* tmp = FindLinkList(list,name);
if(NULL == tmp)
{
return 1;
}
memcpy(&tmp->data,data,sizeof(DATATYPE));
return 0;
}
int DestroyLinkList(LinkList *list)
{
LinkNode* tmp = list->head;
while(tmp)
{
list->head= list->head->next;
free(tmp);
tmp = list->head;
}
free(list);
return 0;
}
int InsertTailLinkList(LinkList *list, DATATYPE *data)
{
if(IsEmptyLinkList(list))
{
return InsertHeadLinkList(list,data);
}
else
{
LinkNode* newnode = (LinkNode*)malloc(sizeof(LinkNode));
if(NULL == newnode)
{
perror("inster tail malloc");
return 1;
}
// newnode init
memcpy(&newnode->data,data,sizeof(DATATYPE));
newnode->next = NULL;
newnode->prev=NULL;
LinkNode*tmp = list->head;
while(tmp->next)
{
tmp = tmp->next;
}
newnode->prev = tmp;
tmp->next = newnode;
}
list->clen++;
return 0;
}
int IsEmptyLinkList(LinkList*list)
{
return 0 == list->clen;
}
int GetSizeLinkList(LinkList*list)
{
return list->clen;
}
int InsertPosLinkList(LinkList *list, DATATYPE *data, int pos) {
int len = GetSizeLinkList(list);
if (pos < 0 || pos > len) {
return 1;
}
if (0 == pos) {
return InsertHeadLinkList(list, data);
} else if (len == pos) {
return InsertTailLinkList(list, data);
} else {
LinkNode *tmp = list->head;
int i = 0;
for (i = 0; i < pos - 1; i++) {
tmp = tmp->next;
}
LinkNode *newnode = (LinkNode *)malloc(sizeof(LinkNode));
if (NULL == newnode) {
perror("insert pos malloc");
return 1;
}
memcpy(&newnode->data, data, sizeof(DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
newnode->prev = tmp;
newnode->next = tmp->next;
tmp->next->prev = newnode;
tmp->next = newnode;
}
list->clen++;
return 0;
}
函数头:
#ifndef _DLINK_H_
#define _DLINK_H_
typedef struct person {
char name[32];
char sex;
int age;
int score;
}DATATYPE;
typedef enum{DIR_FORWARD,DIR_BACKWARD}DIRECT;
typedef struct node {
DATATYPE data;
struct node *next,*prev;
}LinkNode;
typedef struct list {
LinkNode *head;
int clen;
}LinkList;
LinkList *CreateLinkList();
int InsertHeadLinkList(LinkList *list, DATATYPE *data);
int ShowLinkList(LinkList *list ,DIRECT dir);
LinkNode *FindLinkList(LinkList *list, char *name);
int DeleteLinkList(LinkList *list, char *name);
int ModifyLinkList(LinkList *list, char *name, DATATYPE *data);
int DestroyLinkList(LinkList *list);
int InsertTailLinkList(LinkList *list, DATATYPE *data);
int IsEmptyLinkList(LinkList*list);
int GetSizeLinkList(LinkList*list);
int InsertPosLinkList(LinkList*list,DATATYPE*data,int pos);
#endif
主函数,测试功能函数是否正确:
#include "dlink.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
LinkList* ll = CreateLinkList();
DATATYPE data[]={
{"zhangsan",'m',20,80},
{"lisi",'f',21,82},
{"wangmazi",'f',22,70},
{"lao6",'f',30,70},
{"zhaosi",'f',30,50},
};
InsertHeadLinkList(ll,&data[0]);
InsertHeadLinkList(ll,&data[1]);
InsertHeadLinkList(ll,&data[2]);
ShowLinkList(ll,DIR_FORWARD);
printf("-------back---------\n");
ShowLinkList(ll,DIR_BACKWARD);
printf("-------find---------\n");
char want_name[50]="li1si";
LinkNode*tmp = FindLinkList(ll,want_name);
if(NULL == tmp)
{
printf("can't find %s\n",want_name);
}
else
{
printf("%s %d\n",tmp->data.name,tmp->data.age);
}
printf("----------modify---------\n");
ModifyLinkList(ll,"wangmazi",&data[3]);
ShowLinkList(ll,DIR_FORWARD);
/*
printf("----------del---------\n");
DeleteLinkList(ll,"lisi");
ShowLinkList(ll,DIR_FORWARD);
printf("-------back---------\n");
ShowLinkList(ll,DIR_BACKWARD);
*/
/* printf("--------------tail---------------\n");
InsertTailLinkList(ll, &data[4]);
ShowLinkList(ll,DIR_FORWARD);
printf("-------back---------\n");
ShowLinkList(ll,DIR_BACKWARD);
*/
printf("--------------pos---------------\n");
InsertPosLinkList(ll, &data[4],3);
ShowLinkList(ll,DIR_FORWARD);
printf("-------back---------\n");
ShowLinkList(ll,DIR_BACKWARD);
DestroyLinkList(ll);
printf("hello\n");
return 0;
}