C语言 学习结构指针并解决leetcode 合并K个升序链表
最近为了更好的学习数据结构,开始学习了C语言,在学习过程中,了解到C语言里是没有对象和类,但是为了可以实现复杂数据结构,提供了结构体:
struct Person{
char *fristName;
char *lastName;
};
//声明1
struct Person a1 = {"James","Harden"};
//声明2
struct Person a2 = {.firstNme="James",.lastName="Harden"};
//两种方式都是可以的,也可以只赋值一个
struct Person a3 = {"James"};
struct Person a4 = {.firstNme="James"};
这和平时使用的js访问方式也是类似的
a1.firstName;
a1.lastName;
但是最大的不同就是C语言拥有强大指针,而js是没有的,所以操作结构体的方式是灵活多变的,当我们想要对结构体本身进行操作时可以选择传入结构指针,如果只是需要用到结构体,那直接传结构体(副本)也是无妨的:
struct Person
{
char *firstName;
char *lastName;
};
void chage(struct Person *p)
{
p->firstName = "abc";
//也可以 (*p).firstName = "abc";
};
int main(int argc, char *argv[])
{
struct Person a1 = {"James", "Harden"};
printf("%s\n", a1.firstName);//打印James
//传递结构地址
chage(&a1);
printf("%s\n", a1.firstName);//打印abc
return 0;
};
在学习了结构体之后,试着利用C语言来解决链表问题(合并K个升序链表),加深印象:
//思路
//1.多个链表,可以两两合并
//2.涉及到排序问题,也可以创建最小堆,把链表的值都往堆里放,在堆里
//会进行从小到大的排序,然后依次取出来,赋值到新链表
//在这里我使用方法1
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//返回结构指针
struct ListNode * merge(struct ListNode *l1,struct ListNode *l2){
//创建链表指针
struct ListNode * head = malloc(sizeof(struct ListNode));
struct ListNode *p = head;
while(l1&&l2){
if(l1->val<=l2->val){
p->next = l1;
//向下滑动
l1 = l1->next;
}else{
p->next = l2;
//向下滑动
l2 = l2->next;
};
//向下滑动
p = p->next;
};
//如果两个链表中有一个指针不为NULL,说明这个链表还没比较完,剩下的
//所有值肯定是比另一个链表的值都大,直接拼接到新链表后面就可以了
p->next = l1?l1:l2;
return head->next;
};
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize){
//首先需要创建一个新链表
struct ListNode *newListNode = NULL;
//依次取出链表,并与前一个合并链表进行比较合并
for(int i = 0;i<listsSize;i++){
newListNode= merge(newListNode,lists[i]);
};
return newListNode;
}
总结:结构体的存在,同时利用指针,给予了程序员很大的创造空间。在学习C语言过程中,会发现C语言选择相信程序员,特别是性能方面,需要程序员自己去考虑问题,程序也许能跑起来,结果错的离谱是常有的事,所以需要把基础打好。