指针:
1、几个易混淆的点:
- int p; //这是一个普通的整型变量
- int *p; //首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int 型.所以P是一个返回整型数据的指针
- int p[3]; //首先从P 处开始,先与[]结合,说明P 是一个数组,然后与int 结合,说明数组里的元素是整型的,所以P 是一个由整型数据组成的数组
- int *p[3]; //首先从P 处开始,先与[]结合,因为其优先级比*高,所以P 是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与int 结合,说明指针所指向的内容的类型是整型的,所以P 是一个由返回整型数据的指针所组成的数组
- int (*p)[3]; //首先从P 处开始,先与*结合,说明P 是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P 是一个指向由整型数据组成的数组的指针
2、指针与数组:
数组名可以认为是一个指针,它指向数组的第 0 个元素。 在 C 语言中,我们将第 0 个元素的地址称为数组的首地址。
int arr[5] = {1,2,3,4,5};
int* ptr = arr;
for (int i = 0; i < 5; i++) {
printf("%d\n",*ptr);
ptr++;
}
哈希表的用法:
1、引用头文件
#include "uthash.h"
2、自定义哈希表结构体(哈希表里面存储的是键值对key-value)
注意:一定要包含UT_hash_handle hh(在之后的个别函数中可能会用到这个UT_hash_handle);hh不需要初始化,它可以命名为任何名称,一般都命名为hh。
struct hashTable {
int key;
int val;
//使这个结构体变成可哈希的类型
UT_hash_handle hh;
};
hashTable其实就是哈希表中存储的一个元素
3、定义一个结构体指针,必须为其赋值
struct hashTable* hashtable=NULL;
4、查找元素
struct my_struct *find_user(int user_id) { // 返回哈希结构体类型的变量
struct my_struct *s;
HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */
return s; // 如果存在就返回正确的地址,反之返回空地址NULL
}
在上述代码中,第一个参数users是哈希表,第二个参数是user_id的地址(一定要传递地址)函数的用法而已不必太在意原理。最后s是输出变量。当可以在哈希表中找到相应键值时,s返回给定键的结构,当找不到时s返回NULL。
5、添加元素
void insert(int ikey, int ival) {
struct hashTable* it = find(ikey);
//先判断哈希表中是否已有相同的key存在,若不存在则创建一个新的哈希表元素结构并插入到对应key的位置
if (it == NULL) {
struct hashTable* tmp = malloc(sizeof(struct hashTable));
tmp->key = ikey, tmp->val = ival;
HASH_ADD_INT(hashtable, key, tmp);
}
//如果已存在相同的key,则只修改原有的元素的value值
else {
it->val = ival;
}
}
哈希表使用案例:
【两数之和(力扣)】
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
【思路及算法】
注意到方法一的时间复杂度较高的原因是寻找 target - x 的时间复杂度过高。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。
使用哈希表,可以将寻找 target - x 的时间复杂度降低到从O(N) 降低到 O(1)。
这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/two-sum/solution/liang-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
struct hashTable {
int key;
int val;
UT_hash_handle hh;
};
struct hashTable* hashtable;
struct hashTable* find(int ikey) {
struct hashTable* tmp;
HASH_FIND_INT(hashtable, &ikey, tmp);
return tmp;
}
void insert(int ikey, int ival) {
struct hashTable* it = find(ikey);
if (it == NULL) {
struct hashTable* tmp = malloc(sizeof(struct hashTable));
tmp->key = ikey, tmp->val = ival;
HASH_ADD_INT(hashtable, key, tmp);
} else {
it->val = ival;
}
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
hashtable = NULL;
for (int i = 0; i < numsSize; i++) {
struct hashTable* it = find(target - nums[i]);
if (it != NULL) {
int* ret = malloc(sizeof(int) * 2);
ret[0] = it->val, ret[1] = i;
*returnSize = 2;
return ret;
}
insert(nums[i], i);
}
*returnSize = 0;
return NULL;
}