因为本人要准备考研了,关于前端的东西占比会变少,不过还是和计算机相关的内容,大家多了解一点也无妨。最近在复习901数据结构与算法设计,当然也是各大公司笔试题的一部分。主要代码都是c/c++,因为四年没写了,突然上手写的很渣==如果有需要改进的地方请留言,我看到会及时的修改。
有图片上传不成功点击github原文
创建链表
头插入
#include<iostream>
#include "stdio.h"
#include "stdlib.h"
using namespace std;
struct LNode{
int data; // 数据域
LNode *next; // 指向自身的指针域
};
typedef LNode *LinkList;
LinkList createLinkList Head(){
LinkList L;
LinkList p;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
cin>> x;
while(x!=0) {
p=(LinkList)malloc(sizeof(LNode));
p->data=x;
p->next=L->next;
L->next=p;
cin>>x;
};
return L;
}
int main(){
createLinkListHead();
}
查找
按序号查
LinkList findNodeByOrder(LinkList L,int target){
LinkList p=L;
int i=0;
while(i<target&&p->next!=NULL){
p=p->next;
i++;
}
if(i==target){
return p;
}
return NULL;
}
按数据查
int findNodeByValue(LinkList L,int target){
LinkList p=L;
while(p->data!=target&&p->next!=NULL){
p=p->next;
}
return p->data;
}
插入
指定在某个序号前插入某个值
LinkList insertBefore(LinkList L,int s,int target){ // target为指定插入位置的数据域为s的节点
LinkList p=L;
LinkList newNode=(LinkList)malloc(sizeof(LNode));
newNode->data=s;
int i=0;
if(target<1){
printf("参数target错误");
exit(1);
}
while(i<target-1){
i++;
p=p->next;
}
// 现在的p是目标节点的前驱
newNode->next=p->next;
p->next=newNode;
return L;
}
删除
删除单链表第i个节点
LinkList deleteByOrder(LinkList L,int i){
// 仍然是找前驱
LinkList p=L;
LinkList q;
int j=0;
while(j<i-1){
p=p->next;
j++;
}
if(p==NULL||j>i-1){
printf("参数i错误");
exit(1);
}
q=p->next; // 目标节点
p->next=q->next;
free(q);
return L;
}
双向链表
创建双向链表
struct DuLNode{
int data;
DuLNode *next;
DuLNode *prior;
};
typedef DuLNode *DuLinkList;
DuLinkList createDoubleLinkList(){
DuLinkList head,L;
DuLinkList p;
int x;
L=(DuLinkList)malloc(sizeof(DuLNode));
head=L;
cin>>x;
while(x!=0){
p=(DuLinkList)malloc(sizeof(DuLNode));
p->data=x;
p->next=NULL;
p->prior=L;
L->next=p;
L=p;
cin>>x;
}
return head;
}
双向链表插入节点
在双向链表第i个节点前插入数据域为x的节点。还是先连后断,因为是双向链表有前驱指针不用找第i+1个元素了。先把新节点s的前驱后继连上,然后断开目标节点p的前驱节点的后继指针,将他连到s上,然后再操作目标节点p的前驱指向新节点!!
DuLinkList DuLinkInsert(DuLinkList L,int i,int x){
DuLinkList head,s,p;
int n=0;
p=L;
head=L;
s=(DuLinkList)malloc(sizeof(DuLNode));
s->data=x;
while(n<i){
p=p->next;
n++;
}
if(i==n){
s->next=p;
s->prior=p->prior;
p->prior->next=s;
p->prior=s;
return head;
}else{
cout<<"参数i错误"<<endl;
exit(1);
}
}
双链表删除节点
还是删除i位置的节点p,p的前驱节点的后继与p的后继相同,p的后继节点的前驱与p的前驱指针相连,释放p。
DuLinkList DuLinkDelete(DuLinkList L,int i){
DuLinkList head,p;
int n=0;
p=L;
head=L;
while(n<i){
p=p->next;
n++;
}
if(i==n){
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
return head;
}else{
cout<<"参数i错误"<<endl;
exit(1);
}
}
扩展
合并两个链表
Node* mergelistByOrder(Node *l1,Node *l2){
Node *head,*L;
L=new Node;
L->next=NULL;
L->data=0;
head=L;
while(l1&&l2){
if(l1->data<l2->data){
L->next=l1;
l1=l1->next;
}else{
L->next=l2;
l2=l2->next;
}
L=L->next;
}
if(l1){
L->next=l1;
}
if(l2){
L->next=l2;
}
return head->next;
}
链表原地逆置
原地逆置需要两个指针p,q,和一个临时指针t。q是p的后继,然后将q->next指向p。最终循环完要先断开头节点与这个链表之间的后继关系,将头节点的后继指向p。具体见这个图示->链表原地反转
Node* reverse(Node* L){
Node *p,*q,*t,*head;
head=L;
p=head->next;
q=head->next->next;
while(q!=NULL){
t = q->next;
q->next = p;
p = q;
q = t;
}
head->next->next=NULL;
head->next=p;
return head;
}
两个升序链表,降序合并
- 第一个方法是将上面两个方法结合起来,先按顺序合并,然后逆置。
- 第二个方法是通过头插法,选择最小的先插入。
Node* mergelistByDescOrder(Node *l1,Node *l2){
Node *L,*head,*t,*q;
L=new Node();
head=L;
while(l1&&l2){
if(l1->data<l2->data){
t=l1;
l1=l1->next;
}else {
t=l2;
l2=l2->next;
}
t->next=L->next;
L->next=t;
//L=t;
t=NULL;
}
// 如果l1和l2循环之后还有剩余的节点,按顺序依次添加到头节点之后
if(l1){
t=l1;
}
if(l2){
t=l2;
}
while(t){
q=t;
t=t->next;
q->next=L->next;
L->next=q;
}
return head->next;
}