目录
5.遍历一次,删除倒数第 k 个结点(k从1开始),不能用替换删除法
1.单链表反转
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
}ListNode;
void print(ListNode *head){
while(head!=NULL){
cout<<head->value<<" ";
head=head->next;
}
return;
}
ListNode* reverse(ListNode* head){
ListNode* tmp=head;
head=NULL;
while(tmp){
ListNode* tmpp=tmp;
tmp=tmp->next;
tmpp->next=head;
head = tmpp;
}
return head;
}
int main(){
ListNode *head=(ListNode*)malloc(sizeof(ListNode));
ListNode *HEAD = (ListNode *)malloc(sizeof(ListNode));
int n;
cin>>n;
for(int i=0;i<n;i++){
ListNode *headd=(ListNode*)malloc(sizeof(ListNode));
int value;
cin>>value;
headd->value=value;
headd->next = NULL;
if(i!=0){
head->next=headd;
}else{
HEAD = headd;
}
head=headd;
}
HEAD=reverse(HEAD);
print(HEAD);
system("pause");
return 0;
}
2.不遍历链表删除非尾节点
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
}ListNode;
void DelNotTail(ListNode *pDel){
ListNode *pDelnext = pDel->next;
pDel->value = pDelnext->value;
pDel->next = pDelnext->next;
free(pDelnext);
return;
}
void print(ListNode *head){
while(head!=NULL){
cout << head->value<<" ";
head = head->next;
}
return;
}
ListNode* initList(int arr[],ListNode *head,int n){
ListNode *HEAD =head;
for (int i = 0; i < n;i++){
ListNode *headd = (ListNode*)malloc(sizeof(ListNode));
head->value = arr[i];
if(i!=n-1){
head->next = headd;
head = headd;
}else
head->next = NULL;
}//初始化的时候,尾节点->next=NULL,而不是一个空节点。
return HEAD;
}
int main(){
int arr[7] = { 1, 2, 3, 4, 5, 6, 7 };
ListNode *head = (ListNode*)malloc(sizeof(ListNode));
ListNode *HEAD=initList(arr, head, 7);
while(head){
if(head->value==4){
DelNotTail(head);
break;
}else head = head->next;
}
print(HEAD);
system("pause");
return 0;
}
3.遍历一次,找到中间节点
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
}ListNode;
ListNode* initList(int a[],ListNode *head,int n){
ListNode *HEAD = head;
for (int i = 0; i < n;i++){
ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
head->value = a[i];
if(i!=n-1){
head->next = headd;
head = headd;
}else head->next = NULL;
}
return HEAD;
}
ListNode* FindMid(ListNode* head){
ListNode *one =head;
ListNode *two =head;
while(two->next!=NULL){
one = one->next;
two = two->next;
if(two->next!=NULL) two = two->next;
else break;
}
return one;
}
int main(){
int a[9] = {1, 2, 3, 4, 5, 6, 7,9};
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
head = initList(a, head, 9);
head = FindMid(head);
cout << head->value;
system("pause");
return 0;
}
4.遍历一次,找到倒数第 k 个结点(k从1开始)
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
ListNode* findK(ListNode* head,int k){
ListNode *one = head;
ListNode *two = head;
for (int i = 0; i < k;i++){
two = two->next;
}
while(two){
one = one->next;
two = two->next;
}
return one;
}
int main(){
int n;
cin >> n;
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
ListNode *HEAD = head;
for (int i = 0; i < n;i++){
ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
int value;
cin >> value;
head->value = value;
if(i!=n-1){
head->next = headd;
head = headd;
}else
head->next = NULL;
}
ListNode *tmp = findK(HEAD, 3);
cout << tmp->value << endl;
system("pause");
return 0;
}
5.遍历一次,删除倒数第 k 个结点(k从1开始),不能用替换删除法
找到倒数第k+1个节点,其next就是倒数第k个节点。
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
ListNode* findKDel(ListNode *head,int k){
ListNode *one = head;
ListNode *two = head;
for (int i = 0; i < k + 1;i++){
two = two->next;
}
while(two){
one = one->next;
two = two->next;
}
ListNode *tmp = one->next;
one->next = tmp->next;
free(tmp);
return head;
}
void print(ListNode* head){
while(head){
cout << head->value << " ";
head = head->next;
}
return;
}
int main(){
int n,k;
cin >> n>>k;
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
ListNode *HEAD = head;
for (int i = 0; i < n;i++){
int value;
cin >> value;
ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
head->value = value;
if(i!=n-1){
head->next = headd;
head = headd;
}else
head->next = NULL;
}
if(n==k){
head = HEAD->next;
free(HEAD);
HEAD = head;
}
else
findKDel(HEAD, k);
print(HEAD);
system("pause");
return 0;
}
6.合并两个有序链表
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
ListNode *addList(ListNode *headA,ListNode *headB){
ListNode *head = NULL;
if(headA==NULL) return headB;
if(headB==NULL) return headA;
if(headA->value<headB->value){
head=headA;
headA = headA->next;
}
else{
head = headB;
headB = headB->next;
}
ListNode *HEAD = head;
while (headA && headB) {
if (headA->value < headB->value) {
head->next= headA;
head = head->next;
headA = headA->next;
}
else {
head->next= headB;
head = head->next;
headB = headB->next;
}
}
if(headA) head->next=headA;
if(headB) head->next=headB;
return HEAD;
}
void print(ListNode *head){
while(head){
cout << head->value << " ";
head = head->next;
}
return;
}
int main(){
int a[] = {1, 3, 5, 7};
int b[] = {2, 5};
ListNode *A = (ListNode *)malloc(sizeof(ListNode));
ListNode *B = (ListNode *)malloc(sizeof(ListNode));
ListNode *headA = A, *headB = B;
for (int i = 0; i < 4;i++){
ListNode *tmp = (ListNode *)malloc(sizeof(ListNode));
A->value = a[i];
if(i!=3){
A->next = tmp;
A = tmp;
}
else if(i==0) headA = A;
else A->next = NULL;
}
for (int i = 0; i < 2;i++){
ListNode *tmp = (ListNode *)malloc(sizeof(ListNode));
B->value = b[i];
if(i!=1){
B->next = tmp;
B = tmp;
}
else if(i==0) headB = B;
else B->next = NULL;
}
ListNode *res = addList(headA, headB);
print(res);
system("pause");
return 0;
}
7.判断链表是否有环,求环的长度和入口点
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
ListNode* enter(ListNode *head){
ListNode *fast = head;
ListNode *slow = head;
if(head==NULL) return NULL;
slow = slow->next;
if(fast->next!=NULL) fast = fast->next->next;
while(fast && fast!=slow){
slow = slow->next;
if(fast->next!=NULL) fast = fast->next->next;
}
if(fast==NULL) return NULL;
slow = head;
while(slow!=fast){
slow=slow->next;
fast = fast->next;
}
cout << fast->value << endl;
return fast;
}
int dis(ListNode *head){
ListNode *en = enter(head);
ListNode *tmp = en->next;
int res = 1;
while(tmp!=en){
tmp = tmp->next;
res++;
}
return res;
}
void print(ListNode *head){
int i = 0;
while(head && i<10){
i++;
cout << head->value << " ";
head = head->next;
}
return;
}
int main(){
int n;
cin >> n;
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
ListNode *HEAD = (ListNode *)malloc(sizeof(ListNode));
ListNode *en = (ListNode *)malloc(sizeof(ListNode));
for (int i = 0; i < n;i++){
int value;
cin >> value;
ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
head->value = value;
if(i==0){
head->next = headd;
HEAD = head;
head = headd;
}else if(i!=n-1 && i!=3){
head->next = headd;
head = headd;
}else if(i==3){
head->next = headd;
en = head;
head = headd;
}else head->next = en;
}
print(HEAD);
cout << dis(HEAD);
system("pause");
return 0;
}
8.判断两个不带环的链表是否相交,若相交,求交点。
lenA,lenB,长度差
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
ListNode *getJoinP(ListNode *headA,ListNode *headB){
int lenA = 0, lenB = 0;
ListNode *HeadA = headA, *HeadB = headB;
while(HeadA!=NULL){
lenA++;
HeadA = HeadA->next;
}
while(HeadB!=NULL){
lenB++;
HeadB = HeadB->next;
}
HeadA = headA;
HeadB = headB;
if(lenB>lenA){
for (int i = 0; i < lenB - lenA;i++) HeadB = HeadB->next;
}else if(lenB<lenA){
for (int i = 0; i < lenA - lenB;i++) HeadA = HeadA->next;
}
while(HeadA!=HeadB){
HeadA = HeadA->next;
HeadB = HeadB->next;
}
return HeadA;
}
void print(ListNode *head){
while(head){
cout << head->value << " ";
head = head->next;
}
return;
}
int main(){
int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int b[10] = {10, 9, 8, 7, 6, 5, 6,7,8,9};
ListNode *headA = (ListNode *)malloc(sizeof(ListNode));
ListNode *headB = (ListNode *)malloc(sizeof(ListNode));
ListNode *HEADA=(ListNode *)malloc(sizeof(ListNode));
ListNode *HEADB=(ListNode *)malloc(sizeof(ListNode));
for (int i = 0; i <3;i++){
ListNode *headdA = (ListNode *)malloc(sizeof(ListNode));
headA->value = a[i];
if(i==0){
HEADA = headA;
headA->next = headdA;
headA = headdA;
}else if(i!=2){
headA->next = headdA;
headA = headdA;
}
}
for (int i = 0; i < 10;i++){
ListNode *headdB= (ListNode *)malloc(sizeof(ListNode));
headB->value = b[i];
if(i==0){
HEADB = headB;
headB->next = headdB;
headB = headdB;
}else if(i<3 || i>3 && i!=9){
headB->next = headdB;
headB = headdB;
}else if(i==3){
headA->next = headB;
headB->next = headdB;
headB = headdB;
}else{
headB->next = NULL;
}
}
ListNode *tmpp = getJoinP(HEADA, HEADB);
print(HEADA);cout << endl;
print(HEADB);cout << endl;
cout << tmpp->value;
system("pause");
return 0;
}
9.可能带环的两个链表的交点
1)两个都不带环,见8的解法
2)两个链表,一个带环,一个不带,这样一定不相交
3)两个都带环,有以下几种情况:
- 当出现①情况时,两个链表不相交。
- 当出现②情况时,两个链表的交点在环外,那么我们可以转化为不带环链表判断相交即可。
- 当出现③情况时,两个链表的交点在环内,那么我们可以遍历其中一个链表的环,若在环内与另一个链表环的入口点相交,则两个链表相交,相遇点即为两个链表的交点。
- 要判断为情况②还是情况③,只需判断两个链表环的入口点是否相同即可。
10.约瑟夫环
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。 求,最后一个出列的人的编号。
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
ListNode *initList(int a[],ListNode *head,int n){
ListNode *HEAD = head;
for (int i = 0; i < n;i++){
ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
if(i!=n-1){
head->value = a[i];
head->next = headd;
head = headd;
}else{
head->value = a[i];
head->next = HEAD;
}
}
return HEAD;
}
int main(){
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
head = initList(a, head, 8);
//第k个人开始从1报数,报到m则出列,下一个人从1继续报数,求最后一个出列的人。
int k=2,m = 3;
for (int i = 1; i < k-1;i++){
head = head->next;
}
ListNode *pre = head;
head = head->next;
while (pre!=head){
for (int i = 1; i < m;i++){
head = head->next;
pre = pre->next;
}
pre->next = head->next;
free(head);
head = pre->next;
}
cout << pre->value;
system("pause");
return 0;
}
11.冒泡排序用单链表实现
#include<iostream>
using namespace std;
typedef struct ListNode{
int value;
ListNode *next;
} ListNode;
void print(ListNode *head){
while(head){
cout << head->value << " ";
head = head->next;
}
return;
}
ListNode *BubbleSort(ListNode *head,int n){
ListNode *HEAD=head,*tmp=head->next,*pre=NULL;
for (int i = 0; i < n;i++){
tmp = HEAD->next;
head = HEAD;
pre = NULL;
for (int j = i; j < n-1;j++){
if(tmp->value<head->value){
if(pre==NULL){
head->next = tmp->next;
tmp->next = head;
HEAD = tmp;
}else{
pre->next = tmp;
head->next = tmp->next;
tmp->next = head;
}
pre = tmp;
head = pre->next;
tmp = head->next;
}else{
if(pre==NULL){
pre=head;
HEAD = head;
}
head = head->next;
tmp = tmp->next;
}
}
}
return HEAD;
}
int main(){
int a[] = {8, 6, 4, 3, 2, 67};
ListNode *head = (ListNode *)malloc(sizeof(ListNode));
ListNode *HEAD = (ListNode *)malloc(sizeof(ListNode));
for (int i = 0; i < 6;i++){
ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
if(i!=5){
head->value = a[i];
head->next = headd;
if(i==0) HEAD=head;
head = headd;
} else{
head->value = a[i];
head->next = NULL;
}
}
head = BubbleSort(HEAD,6);
system("pause");
return 0;
}