leetcode--从尾到头打印链表

题目

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]

限制:

0 <= 链表长度 <= 10000

代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* reversePrint(struct ListNode* head, int* returnSize){

    if(head == NULL)
    {
        *returnSize = 0;
        return NULL;
    }

    struct ListNode* p =  head;
    int num = 0;
    //怎样判断链表结束
    while(p != NULL)
    {
        p = p->next;
        num ++;
        printf("%d",num);
    }
    int *arr = (int *)malloc(sizeof(int)*num);
    for(int i = num-1; i >= 0; i--)
    {
        arr[i] = head->val;
        head = head->next;
    }
    *returnSize = num;
 return arr;
}
解法2,链表反序后进行输出

/* 链表反序, 并统计出链表长度 */
struct ListNode *reverseList(struct ListNode *head, int *returnSize) {
    if (head == NULL) {
        return NULL;
    }
    struct ListNode *pre = NULL;
    struct ListNode *cur = head;
    struct ListNode *tmp = NULL;
    while (cur != NULL) {
        (*returnSize)++;
        tmp = cur->next;
        cur->next = pre;
        pre = cur;
        cur = tmp;
    }
    return pre;
}

int* reversePrint(struct ListNode* head, int* returnSize){
    int *res = (int*)malloc(sizeof(int) * 10000);
    int i = 0;
    *returnSize = 0;
    /* 链表反序 */
    head = reverseList(head, returnSize);
    res = (int*)malloc(sizeof(int) * (*returnSize));

    /* 遍历链表, 输出链表元素 */
    while (head != NULL) {
        res[i++] = head->val;
        head = head->next;
    }
    return res;
}

知识点

1、链表的结构

链表是有一个结构体,结构体内部分为数据部分和指针部分,数据部分为存放的数值,指针部分存放的是指向下一个节点的指针,代码示例如下:

struct node{
  int val;//数值部分存放内容为int数值
  struct node *next;//指向下一个节点的指针  
}

2、创建一个节点

struct Node* temp=(struct node*)malloc(sizeof(struct node));

3、链表操作时一般需要考虑的点

(1)链表尾部新增元素时

  • 链表中一个节点都没有,即head== NULL,那么这个节点既是头结点也是尾结点;

  • 链表中有节点,

(2)链表中间新增元素,注意不要丢失后面元素

   //创建临时节点,申请内存
	struct node* temp =(struct node *)malloc(sizeof(struct node));
	//节点成员进行赋值
	temp->a=a;
	temp->next=NULL;
 
  //假如p指向要插入的节点位置
	//连接到链表上 1.找到的节点在尾部 2.找到的节点在中间 
  struct node* end = NULL;//找到尾指针
	if (p == end)
	{
	//尾巴的下一个指向新插入的节点
	end->next=temp;
	//新的尾巴
	end=temp;
	}else
	{
	// 先连后面 (先将要插入的节点指针指向原来找到节点的下一个)
	temp->next=p->next;
	//后连前面
	p->next=temp;
	}

注意:数组和链表的区别

对比内容数组链表
内存提前申请大小,在中分配的一块连续区域编译期确定大小,空间利用率低不需提前申请大小,空间动态申请,在中分配空间,运行时才能确定大小,空间利用率高
访问效率效率很高,时间复杂度可以达到O(1):内存空间连续,访问元素时,直接从数组的首地址处向后偏移就可以访问数据时效率低,时间复杂度为O(N):内存空间分散,所以不具有随机访问性,如要需要访问某个位置的数据,需要从第一个数据开始找起,依次往后遍历
插入删除元素效率插入数据和删除数据效率低:插入数据时,待插入位置的的元素和它后面的所有元素需向后移动; 删除数据时,待删除位置后面的所有元素都需要向前移动插入元素和删除元素效率较高
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的修养

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值