c语言的链表如何理解以及插入和遍历

链表的组成

链表是由一个个节点组成,节点中包括有效数据和指针,有效数据就是需要存的数据,指针是为了指向下一个节点,从而使得一个个节点连接起来

创建一个单链表

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node        //定义一个结构体用来创建链表节点
{
int date;
struct node *pnext;
};
struct node* create_node(int date) //定义一个函数用来创建节点,返回值为struct node*类型
{
struct node* p=(struct node*)malloc(sizeof(struct node));//向堆内存申请内存用来存放这个节点
if(NULL==p)                 //检验malloc是否申请成功
printf("malloc error.\n");
bzero(p,sizeof(struct node));//初始化申请到的内存
p->date=date;          //把函数传参的date写入节点
p->pnext=NULL;         //节点中的指针指向空
}
int main(void)
{
struct node* pHeader=NULL;//定义一个头指针
pHeader=create_node(1);     //让头指针指向第一个节点
pHeader->pnext=create_node(2);  //利用头指针指向第一个节点的指针指向第二个节点
pHeader->pnext->pnext=create_node(3); //利用头指针指向第一个节点的指针指向第二个节点的指针指向第三个节点
printf("node1 date=:%d.\n",pHeader->date);//打印第一个节点存的数据
printf("node2 date=%d.\n",pHeader->pnext->date);//打印第二个节点存的数据
printf("node3 date=:%d.\n",pHeader->pnext->pnext->date);//打印第三个节点存的数据
}

输出结果:

node1 date=:1.
node2 date=2.
node3 date=:3.

链表的尾部插入:

实现原理是先找到链表的最后一个节点,然后把最后一个节点的指针指向要插入的那个节点

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node
{
int date;
struct node* pnext;
};
struct node* create_node(int date)
{
struct node *p=(struct node*)malloc(sizeof(struct node));
if(NULL==p)
printf("malloc error.\n");
bzero(p,sizeof(struct node));
p->date=date;
p->pnext=NULL;
}
void insert_tail(struct node*PH,struct node* new)//第一个参数是头指针,第二个参数是插入的节点中的那个指针
{
struct node *p=PH; //定义一个局部变量p指向头指针
while(NULL!=p->pnext)  //找最后一个节点
{
p=p->pnext;      //往后走一个节点
}
p->pnext=new; //让最后一个节点的指针指向要插入的那个节点
}
int main(void)
{
struct node* pHeader=create_node(1);
insert_tail(pHeader,create_node(2));
insert_tail(pHeader,create_node(3));
printf("node1 date=:%d.\n",pHeader->date);
printf("node2 date=:%d.\n",pHeader->pnext->date);
printf("node3 date=:%d.\n",pHeader->pnext->pnext->date);
}










输出结果为:

node1 date=:1.
node2 date=2.
node3 date=:3.

链表的遍历:

void bianli(struct node* PH)
{
struct node* p=PH;
while(NULL!=p->pnext) //一直到最后一个节点指针指向NULL一直执行下面语句进行输出
{
p=p->pnext;       //走向下一个节点
printf("node date=:%d.\n",p->date); //输出当前节点的数据
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
链表的基本方法是使用指针,从链表的头节点开始依次遍每个节点,直到遍链表的尾节点为止。使用BKDRHash的方法可以将链表中的每个节点以哈希表的形式组织起来,这样可以更加高效地查找和访问链表中的节点。 遍使用BKDRHash组织的链表时,需要先定位到哈希表中相应的桶,然后依次访问桶中的每个节点即可。具体的实现方法可以参考下面的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASH_SIZE 10000 // 定义链表节点的结构体 typedef struct ListNode { char* key; char* value; struct ListNode* next; } ListNode; // 定义哈希表的结构体 typedef struct HashTable { ListNode* buckets[HASH_SIZE]; } HashTable; // 计算字符串的哈希值 unsigned int BKDRHash(char* str) { unsigned int seed = 131; // 31、33、131、137、65537等常用的哈希种子 unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return hash % HASH_SIZE; } // 添加节点到哈希表中 void HashTablePut(HashTable* table, char* key, char* value) { unsigned int hash = BKDRHash(key); ListNode* node = table->buckets[hash]; while (node) { if (strcmp(node->key, key) == 0) { // 如果key已经存在,则更新value free(node->value); node->value = strdup(value); return; } node = node->next; } // 如果key不存在,则创建新节点并插入到桶中 node = (ListNode*)malloc(sizeof(ListNode)); node->key = strdup(key); node->value = strdup(value); node->next = table->buckets[hash]; table->buckets[hash] = node; } // 根据key查找节点的value char* HashTableGet(HashTable* table, char* key) { unsigned int hash = BKDRHash(key); ListNode* node = table->buckets[hash]; while (node) { if (strcmp(node->key, key) == 0) { return node->value; } node = node->next; } return NULL; } // 遍哈希表中的节点 void HashTableTraverse(HashTable* table) { for (int i = 0; i < HASH_SIZE; i++) { ListNode* node = table->buckets[i]; while (node) { printf("%s:%s\n", node->key, node->value); node = node->next; } } } // 释放哈希表中的所有节点 void HashTableFree(HashTable* table) { for (int i = 0; i < HASH_SIZE; i++) { ListNode* node = table->buckets[i]; while (node) { ListNode* next = node->next; free(node->key); free(node->value); free(node); node = next; } table->buckets[i] = NULL; } } int main() { HashTable table = {0}; // 添加节点 HashTablePut(&table, "apple", "red"); HashTablePut(&table, "banana", "yellow"); HashTablePut(&table, "orange", "orange"); HashTablePut(&table, "grape", "purple"); // 遍节点 HashTableTraverse(&table); // 查找节点 printf("%s\n", HashTableGet(&table, "apple")); // 释放节点 HashTableFree(&table); return 0; } ``` 这个示例程序实现了一个使用BKDRHash组织的哈希表,使用了链表节点结构体和哈希表结构体,以及相关的操作函数。在遍哈希表时,使用了两个嵌套的while循环,依次遍哈希表中的桶和桶中的节点,然后输出每个节点的key和value。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值