C语言之-链表学习

1、静态链表
#include <stdio.h>
/**
*定义节点结构体
*/
struct sNode{
int num;
struct sNode* next;
}s[3]={{1},{2},{3}};
typedef struct sNode sn;
/**
*静态单链表
*/
int main(void){
sn *p,*head;
head=s; //将数组首址赋给 临时(头)指针 head;
s[0].next=&s[1]; //将节点2的地址赋给节点1的next指针;节点1next指向节点2
s[1].next=&s[2]; //将节点3的地址赋给节点2的next指针;节点2next指向节点3
s[2].next=NULL; //将NULL赋给节点3的next指针; 节点3next指向NULL
p=head; //将头指针赋给 p指针,完成遍历。
printf("num\n");
do{
printf("%d\t\n",p->num);
p=p->next; //因为当p为节点1时,p->next 是节点2的地址,所以执行完后p的地址就是下一个节点地址。
}while(p!=NULL);
return 0;
}

2、动态链表


3、hash 算法,简单来说就是:利用数组可以根据下标快速定位的特性,来实现能快速查询的数据结构。
文件头(list.h),相当地java中的接口。

#include < stdio.h >

#define HASHSIZE 256

//定义hash表中的节点的类型
struct nlist {
struct nlist * next;
char * key;
char * value;
};

//定义接口中的函数,也就是对外来说,这个程序可以做什么
unsigned hash(char * s); //计算一个串的hash值
struct nlist * lookup(char * key); //查找一个value,根据key
struct nlist * install(char * key, char * value); //插入一个key=value的对象


(list.c)实现头文件(list.h)中声明的函数,相当java中具体的实现类。

#include < string.h >
#include "list.h"

static struct nlist * hashtab[HASHSIZE];

/**
*哈希表的做法,就是把Key通过一个固定的算法函数,既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里,而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位。
*/
unsigned hash(char * s) //取得hash值
{
unsigned hashval;

for (hashval = 0; * s != '\0'; s++)
hashval = * s + 31 * hashval;//这里的31并非随意,乃是一个经验值,选取它的目的在于减少冲突,当然,hash冲突这个问题是不能根本避免的。这里只是一个人们在测试中发现的可以相对减少hash冲突的一个数字,可能以后会发现更好的数值来。
return hashval % HASHSIZE;//最简单的hash 算法,就是对一个数进行求余
}

//根据一个键来进行搜索,并返回节点
struct nlist * lookup(char * key) {
struct nlist * np;

for (np = hashtab[hash(key)]; np != NULL; np = np->next)
if (strcmp(key, np->key) == 0)
return np;
return NULL;
}

//用来插入一个新的节点
struct nlist * install(char * key, char * value) {
struct nlist * np;
unsigned hashval;

if ((np = lookup(key)) == NULL) {
np = (struct nlist * )malloc(sizeof(struct nlist));
if (np == NULL || (np->key= strdup(key)) == NULL)
return NULL;
hashval = hash(key);
np->next = hashtab[hashval];
hashtab[hashval] = np;
} else
free((void * )np->value);
if ((np->value= strdup(value)) == NULL)
return NULL;
return np;
}


[quote]
[url=http://my.oschina.net/chape/blog/132533]代码引用的地方[/url]
[/quote]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值