数据结构
链表相关算法题
反转链表1
题源1:反转链表1
比较简单,可以作为思想记忆,不太会这么直接考察
408可能考察链表的实现,
ListNode* reverseList(ListNode* head) {
if(head == NULL) return NULL;
//头插法
ListNode * p = head;//工作指针,指向链表的最后一个位置,由于leetcode没有头结点后面相当于把最后一个结点当作头结点使用
ListNode * q = head;
while(p->next != NULL){
p = p->next;
}
//开始头插
//工作指针
p->next = NULL;
ListNode *r;
while(q != p){
r = q->next;
q->next = p->next;
p->next = q;
q = r;
}
return p;
}
反转链表2
题源2,反转链表2
题解
中等难度+链表,实际上是比较合适考研出题的。
代码量也不大。
- curr:指向待反转区域的第一个节点 left;
- next:永远指向 curr 的下一个节点,循环过程中,curr 变化以后 next 会变化;
- pre:永远指向待反转区域的第一个节点 left 的前一个节点,在循环过程中不变。
ListNode* reverseBetween(ListNode* head, int left, int right) {
//设置dummyNode
ListNode *dummyNode = new ListNode(-1);//设置哑结点,就是头结点
dummyNode->next = head;
//已pre作为头结点进行头插法,使得left到right区域内反转
ListNode * curr; //指向待反转区域的第一个结点
ListNode * cnext; //curr的下一个结点
ListNode * pre; //指向待反转区的前一个结点
pre = dummyNode;
for(int i = 0; i < left - 1; i++){
pre = pre->next;
}
curr = pre->next;
//拉直过后curr自己向后移动了,不需要再curr = curr->next
for(int i = 0; i < right - left; i++){
cnext = curr->next; //记录当前位置的下一个位置
curr->next = cnext->next;
cnext->next = pre->next;
pre->next = cnext;
}
return dummyNode->next;
}
2019年真题-链表逆置(头插法)
题解
可以将头插法逆置分解为以下这几个步骤
注:图示2号是要头插的第一个元素,头结点是1号
-
头结点断开
p->next = NULL;
-
当q不为空结点时,说明有元素进行头插法
(a)工作指针r指向要进行头插元素的后一个元素r=q->next;
(b)头结点的下一个结点指向要进行头插的结点,即为q结点p->next=q;
[p的值是不会在头插过程中发生改变的,头插二字也可从此理解]
©进行头插的结点断开q->next=NULL;
(d)头插下一个结点q=r;
代码
typedef struct LNode{
ElemType data;
struct Lnode *next;
} LNode, *LinkList;
void slove(LinkList * h){
LinkList *p, *q, *r, *s;//工作指针
p = q = h;
//寻找中间结点
while(q->next != NULL){
p = p->next;
q = q->next;
if (p->next != NULL) p = p->next;
}
q = p->next; //令q指向后半段首结点
p->next = NULL;
//将后半段链表逆置
while(q != NULL){
r = q->next;
q->next = p->next;
p->next = q;
q = r;
}
//逐一插入即可
s = h->next;
q = p->next;
p->next = NULL;
while(q != NULL){
r = q->next;
q->next = s->next;
s->next = q;
s = q->next;
q = r;
}
}
拓扑排序相关分析题
计算机组成原理
存储系统相关
关键词:cache-内存-外存、三级存储
指令系统
关键词:MIPS、指令流水线、x86
个人觉得考MIPS的优先级会高于x86
操作系统
PV-生产者消费者
内存管理
关键词:分页、内存和外存