前言
名言:程序 = 数据结构 + 算法
所以最近把《程序员的实用算法》好好看
单向链表
链表也许是比较简单的数据结构了,因为人的认知东西依靠的是模式,链表能很好的对应生活的中车链这个东东了。
链中的一环
关键是如何表示链表中的一环,经典的定义如下:
//节点的定义
struct Node
{
char *City;
int Temp;
struct Node *next;
};
typedef struct Node * Link;
操作
有了数据结构,总要对数据进行操作,下面给出单向链表的一些常规操作。
1、初始化操作
void CreateLite()
{
head = NULL; //头节点
iNodeCount = 0; //节点数量
}
2、增加节点
向一个链表增加一个节点,其实很简单,但是有几种情况要特殊处理:比如空表(说白就是增加第一个节点),最初的时候,都是对其进行特殊处理。
int AddNodeAscend(Link to_add)
{
Link pn,
pre,
curr;
struct Node dumy; //生成一个节点 很好的策略!!!!!
pn = (Link)malloc(sizeof( struct Node));
if ( NULL == pn )
{
return 0;
}
memcpy( pn , to_add ,sizeof(struct Node));
dumy.next = head;
pre = &dumy;
curr = head;
int i;
for (; curr != NULL ; pre = curr, curr = curr->next)
{
}
pre->next = pn;
pn->next = curr;
head = dumy.next;
return 1;
}
3、删除节点
int DeleNode(Link to_Del)
{
Link curr,
pre;
int i;
if ( NULL == head )
{
return 0;
}
for ( pre = NULL , curr = head; curr != NULL;pre = curr, curr = curr->next)
{
i = NodeCmp(to_Del, curr);
if ( curr != NULL && 0 ==i )
{
if ( pre)
{
pre->next = curr->next;
}
else
{
head = curr->next;
}
FreeNode(curr);
iNodeCount -= 1;
return 1;
}
}
return 0;
}
4、释放内存操作(很关键,不让内存泄露!)
void FreeNode(Link to_free)
{
free( to_free->City );
free(to_free);
}
总结
单向链表较为简单,很好使用,但是也存在一定的局限性。
附录(给出完整的定义)
#ifndef LINK_H
#define LINK_H
//链表的声明
struct Node
{
char *City;
int Temp;
struct Node *next;
};
typedef struct Node * Link;
int AddNodeAscend(Link to_add); //以降序的形式加入一个节点
void CreateLite( void ); //初始化一个链表
int DeleNode( Link to_Del); //删除一个节点
int DuplicateNode( Link , Link ); //处理多重插入
void FreeNode(Link to_free); //释放一个节点
void ShowNode( void ); //形式节点
int NodeCmp(Link , Link ) ; //比较两个节点
#endif
#include "Link.h"
#include <stdlib.h>
#include <string>
Link head;
int iNodeCount;
int AddNodeAscend(Link to_add)
{
Link pn,
pre,
curr;
struct Node dumy; //生成一个节点
pn = (Link)malloc(sizeof( struct Node));
if ( NULL == pn )
{
return 0;
}
memcpy( pn , to_add ,sizeof(struct Node));
dumy.next = head;
pre = &dumy;
curr = head;
int i;
for (; ; pre = curr, curr = curr->next)
{
if ( NULL == curr )
{
break; //到达末尾
}
i = NodeCmp(pn,curr);
if ( i <= 0 )
{
break;
}
}
if ( curr && 0 == i)
{
if ( 0 == DuplicateNode(curr ,pn ) )
{
return 1;
}
}
pre->next = pn;
pn->next = curr;
head = dumy.next;
return 1;
}
int DuplicateNode( Link inLinst, Link duplicate)
{
FreeNode(duplicate);
return 0;
}
int DeleNode(Link to_Del)
{
Link curr,
pre;
int i;
if ( NULL == head )
{
return 0;
}
//curr = head;
//i = NodeCmp(to_Del,curr);
for ( pre = NULL , curr = head; curr != NULL;pre = curr, curr = curr->next)
{
i = NodeCmp(to_Del, curr);
if ( curr != NULL && 0 ==i )
{
if ( pre)
{
pre->next = curr->next;
}
else
{
head = curr->next;
}
FreeNode(curr);
iNodeCount -= 1;
return 1;
}
}
return 0;
}
int NodeCmp(Link a, Link b)
{
if ( a->Temp != b->Temp )
{
return a->Temp - b->Temp;
}
else
{
return strcmp(a->City ,b->City);
}
}
void CreateLite()
{
head = NULL;
iNodeCount = 0;
}
void FreeNode(Link to_free)
{
free( to_free->City );
free(to_free);
}
void ShowNode()
{
Link pn;
int count, median;
for ( count = 0 ,pn = head;pn;pn = pn->next)
{
count +=1;
}
median = count/2+1;
if ( count)
{
count = 0;
for ( pn = head; pn;pn = pn->next)
{
printf("%-20s: %3d",pn->City,pn->Temp);
count += 1;
if ( count == median )
{
printf("----Median-----");
}
printf("\n");
}
}
else
{
printf("Empty list\n");
}
}