1.链表实现
/*
* 链表:插入 O(1) 查找 O(n)
* 线性表:插入 O(logn) 查找 O(1)
* 链表优点:不需要预先知道数据大小;
* 链表缺点:不能随机存取,增加了节点的指针域,空间开销大
*/
#include <stdio.h>
#include <stdlib.h>
#define Error( Str ) FatalError( Str )
#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
typedef int ElementType;
#ifndef _LIST_H
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
//List MakeEmpty(List L);
int IsEmpty(List L);
int IsLast(Position P, List L);
int Find(ElementType X, List L);
void Delete(ElementType X, List L);
Position FindPrevious(ElementType X, List L);
Position Insert(ElementType X, List L, Position P);
void DeleteList(List L);
//Position Header(List L);
//Position First(List L);
//Position Advance(Position P);
//ElementType Retrieve(Position P);
#endif /* _LIST_H */
struct Node
{
ElementType Element;
Position Next;
};
/*初始化*/
int InitList(List *L)
{
*L = (List)malloc(sizeof(List));
if(!*L)
return 0;
(*L)->Next = NULL;
}
/* 判断链表是否为空
* L里为链接的头节点,当头节点里的Next为空时,整个链表为空
*/
int IsEmpty(List L)
{
return L->Next == NULL;
}
/*
* 判断是否是链表的最后一个元素
*/
int IsLast( Position P, List L )
{
return P->Next == NULL;
}
/*
* 判断值X是在链表中的第几个节点
*/
int Find(ElementType X, List L)
{
Position P;
P = L->Next;
int key = 1;
while(P != NULL && P->Element != X)
{
key++;
P = P->Next;
}
return key;
}
/*
* 将第key个节点的值修改为X
*/
void Edit(List L, int key, ElementType X)
{
Position P;
P = L;
int i,compar=0;
//头结点的值不能修改
if(0 != key)
{
for(i=0; i<key; i++)
{
if(P != NULL)
{
P = P->Next;
compar++;
}
else
break;
}
if(key == compar)
P->Element = X;
else
printf("修改失败,该节点不存在!\n");
}
}
/*
* 删除值为X的节点
*/
void Delete(ElementType X, List L)
{
Position P, TmpCell;
P = FindPrevious(X,L);
if(!IsLast(P,L))
{
TmpCell = P->Next;
P->Next = TmpCell->Next;
free(TmpCell);
}
}
/*
* 寻找前驱
*/
Position FindPrevious(ElementType X, List L)
{
Position P;
P = L;
while(P->Next != NULL && P->Next->Element != X)//当P->Next为NULL时,说明已到链表的末尾
P = P->Next;
return P;
}
/*
* 将数据X插入到位置P之后
*/
Position Insert(ElementType X, List L, Position P)
{
Position TmpCell;
TmpCell = malloc(sizeof(struct Node));
if(TmpCell == NULL)
FatalError("Out of space!!!");
TmpCell->Element = X;
TmpCell->Next = P->Next;
P->Next = TmpCell;
return TmpCell;
}
/*
* 链表遍历
*/
void TraverseList(List L)
{
int key = 0;
while(L->Next != NULL)
{
key++;
L = L->Next;
printf("节点%d:%d\n", key,L->Element);
}
}
int main()
{
int res;
List single_list = NULL;
res = InitList(&single_list);
//头结点
Position list_position = FindPrevious(0, single_list);
if(res)
{
int len;
char input[10];
int list_val=0,key;
printf("初始化成功,皮卡!\n操作说明:\n");
printf("数据插入:insert 12,将12插入到链表的尾部,皮卡!\n");
printf("数据删除:delete 12,将12这个节点从链表中删除,皮卡!\n");
printf("数据修改:edit 2 13,将节点2的值修改为13,皮卡!\n");
printf("数据查询:find 13,值为13的节点是第几个,皮卡!\n");
printf("其它:traverse,遍历整个数组,退出:exit,皮卡!\n");
//主循环
while(1)
{
//参数接收
int par_key=1,par3=0;
while(1)
{
if(1 == par_key)
scanf("%s", &input);
else if(2 == par_key)
scanf("%d", &list_val);
else if(3 == par_key)
scanf("%d", &par3);
else
break;
char c=getchar();
if(c=='\n')
break;
par_key++;
}
if(strcmp(input , "insert") == 0)
{
//结点新增
list_position = Insert(list_val, single_list, list_position);
printf("插入完成,新插入的值为:%d,下面是目前的链表,皮卡!\n", list_val);
TraverseList(single_list);
}
else if(strcmp(input , "find") == 0)
{
//结点查找
key = Find(list_val, single_list);
printf("该元素位于第%d个节点\n", key);
}
else if(strcmp(input , "delete") == 0)
{
//结点删除
Delete(list_val, single_list);
printf("节点删除完成,要删除的值为:%d,下面是目前的链表,皮卡!\n", list_val);
TraverseList(single_list);
}
else if(strcmp(input, "edit") == 0)
{
//结节修改
Edit(single_list, list_val, par3);
TraverseList(single_list);
}
else if(strcmp(input , "traverse") == 0)
{
//链表遍历
TraverseList(single_list);
}
else if(strcmp(input , "exit") == 0)
break;
}
}else
FatalError("初始化失败,皮卡!");
}运行结果:
[root@iZ28mhfkaunZ list]# ./list 初始化成功,皮卡! 操作说明: 数据插入:insert 12,将12插入到链表的尾部,皮卡! 数据删除:delete 12,将12这个节点从链表中删除,皮卡! 数据修改:edit 2 13,将节点2的值修改为13,皮卡! 数据查询:find 13,值为13的节点是第几个,皮卡! 其它:traverse,遍历整个数组,退出:exit,皮卡! insert 12 插入完成,新插入的值为:12,下面是目前的链表,皮卡! 节点1:12
2.链表应用
木桶排序->基数排序(基数排序时,需要从低位往高位排,否则不能得出正确结果),多项式的抽象数据类型;