牛马学习数据结构 第六天

1、超级楼梯(典型斐波那契数列)

Problem Description

有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?

Input

输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。

Output

对于每个测试实例,请输出不同走法的数量

Sample Input

2 2 3

Sample Output

1 2

#include <stdio.h>
#include <stdlib.h>

#define eleType int

typedef struct ListNode{
	eleType data;
	struct ListNode *next;
}ListNode;

typedef struct LinkList{
	struct ListNode *head;
	size_t size;
}LinkList;
//初始化链表 
void LinkListInit(LinkList *list){
	list->head=NULL;
	list->size=0;
}
//删除链表 
void LinkListDelete(LinkList *list){
	while(list->head){
		ListNode *temp=list->head;
		list->head=list->head->next;
		free(temp);
	}
	list->size=0; 
}
//插入 
void LinkListInsert(LinkList *list,int index,eleType value){
	if(index<0||index>list->size){
		printf("Invalid Index");
		return ;
	}
	ListNode *NewNode=(ListNode*)malloc(sizeof(eleType));
	NewNode->data=value;
	if(index==0){
		NewNode->next=list->head;
		list->head=NewNode;
	}
	else{
		ListNode *couret=list->head;
		for(int i=0;i<index-1;++i){
			couret=couret->next;
		}
		NewNode->next=couret->next;
		couret->next=NewNode;
	}
	list->size++;
}
//删除某个元素 
void LinkListRemov(LinkList *list,int index){
		if(index<0||index>=list->size){
		printf("Invalid Index");
		return ;
	}
	if(index==0){
		ListNode *couret=list->head;
		couret->next=list->head->next;
		free(list->head);
		list->head=couret; 
	}
	else{
		ListNode *couret=list->head;
		for(int i=0;i<index-1;++i){
			couret=couret->next;
		}
		ListNode *next=couret->next->next;
		free(couret->next);
		couret->next=next;
	}
	list->size--;
}
//查找 
ListNode *LinkListFind(LinkList *list,eleType value){
	ListNode *couret=list->head;
	while(couret){
		if(couret->data==value){
			return couret;
		}
		couret=couret->next;
	}
	return NULL;
} 
//索引 
ListNode *LinkListGet(LinkList *list,int index){
	if(index<0||index>=list->size){
	printf("Invalid Index");
	return NULL;
	}
	ListNode *couret=list->head;
	for(int i=0;i<index;++i){
		couret=couret->next;
	}
	return couret;
} 

void LinkListUpdata(LinkList *list,int index,eleType value){
	ListNode *nod=LinkListGet(list,index);
	if(nod){
		nod->data=value;
	}
}

void LinkListPrintf(LinkList *list){
	ListNode *couret=list->head;
	while(couret){
		printf("%d ->",couret->data);
		couret=couret->next;
	}
	printf("NULL\n");
}
/*
斐波那契数列 
0 1 1 2 3 5 8 13....
i ->data=(i-1)->data + (i-2)->data
*/
int main(){
	LinkList list;
	LinkListInit(&list);
	LinkListInsert(&list,0,0);
	LinkListInsert(&list,1,1);
	for(int i=2;i<40;++i){
		int i_1=LinkListGet(&list,i-1)->data;
		int i_2=LinkListGet(&list,i-2)->data;
		LinkListInsert(&list,i,i_1+i_2);
	}
	int n;
	scanf("%d",&n);
	while(n--){
		int m;
		scanf("%d",&m);
		printf("%d\n",LinkListGet(&list,m)->data);
	}
	LinkListDelete(&list);
	return 0;
}

 2、数列有序

需要稍加修改一下输出函数

Problem Description

有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。

Input

输入数据包含多个测试实例,每组数据由两行组成,第一行是n和m,第二行是已经有序的n个数的数列。n和m同时为0标示输入数据的结束,本行不做处理。

Output

对于每个测试实例,输出插入新的元素后的数列。

Sample Input

3 3 1 2 4 0 0

Sample Output

1 2 3 4

void LinkListPrintf(LinkList *list){
	ListNode *couret=list->head;
	while(couret){
		printf("%d ",couret->data);
		couret=couret->next;
	}
	printf("\n");
}

int main(){
	int n,m;
	while(scanf("%d %d",&n,&m)!=EOF && n!=0 && m!=0){
		LinkList list;
		LinkListInit(&list);
		int x;
		for(int i=0;i<n;++i){
			scanf("%d",&x);
			LinkListInsert(&list,i,x);
		}
		ListNode *node=list.head;
		int pos=0;
		for(int i=0;i<n;++i){
			if(node->data>m){
				break;
			}
			node=node->next;
			pos++;
		}
		LinkListInsert(&list,pos,m);
		LinkListPrintf(&list);
		LinkListDelete(&list);
	}
	return 0;
}

 3、二进制链表转整数

(在链表中存储二进制的方法是从低地址开始存储的就是   0 --> i-1 个位置,而二进制是从右往左是逐渐增大的,比如 链表 0-->i-1 [10110] ,二进制 n<--101101]

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。

请你返回该链表所表示数字的 十进制值 。

示例 1:

输入:head = [1,0,1]
输出:5
解释:二进制数 (101) 转化为十进制数 (5)

示例 2:

输入:head = [0]
输出:0

示例 3:

输入:head = [1]
输出:1

示例 4:

输入:head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
输出:18880

示例 5:

输入:head = [0,0]
输出:0
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
int getDecimalValue(struct ListNode* head) {
    int sum=0;
    while(head){
        sum=sum*2+head->val;
        head=head->next;
    }
    return sum;  
}

4、返回倒数第K个节点 (快慢指针的应用)

实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。

示例:

输入: 1->2->3->4->5 和 k = 2
输出: 4
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


int kthToLast(struct ListNode* head, int k){
    struct ListNode *fast =head;
    while(k--){
        fast=fast->next;
    }
    struct ListNode *slow =head;
    while(fast){
        fast=fast->next;
        slow=slow->next;
    }
    return slow->val;
}

5、训练计划

给定一个头节点为 head 的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第 cnt 个训练项目编号。

示例 1:

输入:head = [2,4,7,8], cnt = 1
输出:8
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* trainingPlan(struct ListNode* head, int cnt) {
    struct ListNode *fast=head;
    while(cnt--){
        fast=fast->next;
    }
    struct ListNode *slow=head;
    while(fast){
        fast=fast->next;
        slow=slow->next;
    }
    return slow;
}

6、删除中间节点 

若链表中的某个节点,既不是链表头节点,也不是链表尾节点,则称其为该链表的「中间节点」。

假定已知链表的某一个中间节点,请实现一种算法,将该节点从链表中删除。

例如,传入节点 c(位于单向链表 a->b->c->d->e->f 中),将其删除后,剩余链表为 a->b->d->e->f

示例:

输入:节点 5 (位于单向链表 4->5->1->9 中)
输出:不返回任何数据,从链表中删除传入的节点 5,使链表变为 4->1->9
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
void deleteNode(struct ListNode* node) {
    struct ListNode *fast=node->next;
    if(fast){
        node->val=fast->val;
        node->next=fast->next;  
        free(fast);
    }
}

7、移除链表中的元素

 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1
输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode *temp;
    while(head && head->val == val){
        temp=head;
        head=head->next;
        free(temp);
    }
    struct ListNode *crut=head;
    while(crut && (temp=crut->next)){
        if(temp->val==val){
            crut->next=crut->next->next;
            free(temp);
        }else{
            crut=crut->next;
        }
    }
    return head;
}

8、删除链表中的节点

有一个单链表的 head,我们想删除它其中的一个节点 node

给你一个需要删除的节点 node 。你将 无法访问 第一个节点  head

链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。

删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:

  • 给定节点的值不应该存在于链表中。
  • 链表中的节点数应该减少 1。
  • node 前面的所有值顺序相同。
  • node 后面的所有值顺序相同。

自定义测试:

  • 对于输入,你应该提供整个链表 head 和要给出的节点 nodenode 不应该是链表的最后一个节点,而应该是链表中的一个实际节点。
  • 我们将构建链表,并将节点传递给你的函数。
  • 输出将是调用你函数后的整个链表。

示例 1:

输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9

示例 2:

输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
void deleteNode(struct ListNode* node) {
    node->val=node->next->val;
    node->next=node->next->next;
}

 9、删除排序链表中重复的元素

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

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

示例 2:

输入:head = [1,1,2,3,3]
输出:[1,2,3]
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(!head){
        return head;
    }
    struct ListNode *temp;
    struct ListNode *crut=head;
    while(crut && (temp=crut->next)){
        if(crut->val==temp->val){
  //          crut->val=crut->next->val;
            crut->next=crut->next->next;
            free(temp);
        }else{
            crut=crut->next;
        }
    }
    return head;
}

Java常考的数据结构包括线性表、栈、队列、树、图等。以下是一些常见的数据结构及其Java实现示例: 1. 线性表 线性表是一种数据结构,其中数据元素按线性顺序排列,每个数据元素最多有一个前驱和一个后继。常见的线性表包括数组和链表。 ```java // 数组实现线性表 int[] arr = new int[]{1, 2, 3, 4, 5}; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } // 链表实现线性表 class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } ListNode head = new ListNode(1); head.next = new ListNode(2); head.next.next = new ListNode(3); while (head != null) { System.out.println(head.val); head = head.next; } ``` 2. 栈 栈是一种后进先出(LIFO)的数据结构,常用于表达式求值、括号匹配等场景。 ```java // 栈的实现 Stack<Integer> stack = new Stack<>(); stack.push(1); stack.push(2); stack.push(3); while (!stack.isEmpty()) { System.out.println(stack.pop()); } ``` 3. 队列 队列是一种先进先出(FIFO)的数据结构,常用于广度优先搜索等场景。 ```java // 队列的实现 Queue<Integer> queue = new LinkedList<>(); queue.offer(1); queue.offer(2); queue.offer(3); while (!queue.isEmpty()) { System.out.println(queue.poll()); } ``` 4. 树 树是一种非线性数据结构,由节点和边组成,每个节点最多有一个父节点和多个子节点。常见的树包括二叉树、二叉搜索树、堆等。 ```java // 二叉树的实现 class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } TreeNode root = new TreeNode(1); root.left = new TreeNode(2); root.right = new TreeNode(3); ``` 5. 图 图是一种非线性数据结构,由节点和边组成,每个节点可以有多个相邻节点。常见的图包括有向图、无向图、加权图等。 ```java // 有向图的实现 Map<Integer, List<Integer>> graph = new HashMap<>(); graph.put(0, Arrays.asList(1, 2)); graph.put(1, Arrays.asList(2)); graph.put(2, Arrays.asList(0, 3)); graph.put(3, Arrays.asList(3)); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值