1.逆转链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {//定义:反转该链表并输出反转后链表的头节点。
if(head==NULL) return NULL;
if(head->next==NULL) return head;
ListNode * root=reverseList(head->next);
ListNode * ans=root;
while(root->next!=NULL){
root=root->next;
}
root->next=head;
head->next=NULL;
return ans;
}
};
2.给定max,min删除链表里那些在(min,max)的元素
```cpp
#include<iostream>
using namespace std;
struct ListNode {
int data;
ListNode* next;
ListNode(int x) {
data = x;
next = NULL;
}
};//找到第一个比min大的,开始删除,看下一个节点和max的关系
ListNode* build() {
int a=0;//输入的元素
ListNode* head,*ans;//尾插法
head = new ListNode(0);
ans = head;
while (a != -1) {
cin >> a;
if (a == -1) return ans;
head->next = new ListNode(a);
head = head->next;
}
head->next = NULL;
return ans;
}
ListNode* delete_element(ListNode* head,int min,int max){
ListNode* res = head;
int flag = 1;
ListNode* first = NULL, * end = NULL, * deletes = NULL;
while (head->next != NULL) {
int a = head->next->data;
if (a > min && a<max && flag) {//记录第一个等下直接桥连
first = head;
flag = 0;
}
//已经记录了上面的first
if (!flag) {
if (a >= max) {//说明当前节点的下一个已经超出了范围了,当前节点应该被删掉
end = head->next;
break;
}
}
head = head->next;
}
if (first == NULL) return res;//这个左数太小了
if (end == NULL) {
first->next = NULL;
return res;
}
deletes = first->next;
cout << "first->data" << first->data << endl;
cout << "end->data" << end->data << endl;
first->next = end;
while (deletes!=end) {
ListNode* net = deletes->next;
free(deletes);
deletes = net;
}
return res;
}
void show(ListNode* head) {
head = head->next;
while (head != NULL) {
cout << head->data << endl;
head = head->next;
}
}
int main() {
ListNode* head = build();
show(head);
int min, max;
cin >> min >> max;
head = delete_element(head, min, max);
show(head);
}
3.双向链表根据访问频次,动态的非递增排序链表
```cpp
#include<iostream>
using namespace std;
struct ListNode {
int data;
int freq;
ListNode* next;
ListNode* prior;
ListNode(int x) {
data = x;
next = NULL;
prior = NULL;
freq = 0;
}
};//找到第一个比min大的,开始删除,看下一个节点和max的关系
ListNode* build() {
int a=0;//输入的元素
ListNode* head,*ans;//尾插法
head = new ListNode(-100);//dummy头
ans = head;
while (a != -1) {
cin >> a;
if (a == -1) return ans;
ListNode*cur= new ListNode(a);
head->next = cur;
cur->prior = head;
head = head->next;
}
head->next = NULL;
return ans;
}
ListNode* Locate(ListNode* head, int x) {//访问并调整位置,如何利用双向链表(删方便)
ListNode* root = head;
ListNode* chang = head;
//在中间处断开
while (root!=NULL) {
if (root->data == x) {
root->freq++;
//断开位置在最后
if (root->next == NULL) {
chang = root;
root->prior->next = NULL;
break;
}
//断开
chang = root;
root->prior->next = root->next;
root->next->prior = root->prior;
break;
}
root = root->next;
}
if (root == NULL) {
printf("查无此数\n");
return head;
}
//找位置插入
root = head;
while (root->next!=NULL) {
if (root->next->freq < chang->freq) {//将chang插入//如果进不去呢
chang->next = root->next;
root->next->prior = chang;
root->next = chang;
chang->prior = root;
return head;
}
root = root->next;
}
//插入位置在最后(freq更新后还是太小了)
root->next = chang;
chang->prior = root;
chang->next = NULL;
}
void show(ListNode* head) {
head = head->next;
while (head != NULL) {
cout << head->data << "fre=="<<head->freq<<endl;
head = head->next;
}
}
int main() {
ListNode* head = build();
show(head);
int a = 0;
while (a!=-1) {
printf("请输入接下来要查找的数x\n");
cin >> a;
Locate(head, a);
show(head);
}
}
4.链表实现约瑟夫
#include<iostream>
using namespace std;
struct ListNode {
int data;
int exist;
ListNode* next;
ListNode* prior;
ListNode(int x) {
data = x;
next = NULL;
prior = NULL;
exist = 1;
}
};//找到第一个比min大的,开始删除,看下一个节点和max的关系
ListNode* build(int x) {
int a=0;//输入的元素
ListNode* head,*ans;//尾插法
head = new ListNode(-100);//dummy头,尾部节点连dummy的下一个,然后维护一个int记录
//链表的大小
ans = head;
while (x>0) {
x--;
cin >> a;
ListNode* cur = new ListNode(a);
head->next = cur;
head = head->next;
}
//成环
head->next = ans->next;
return ans;
}
void delete_say(int m,int n,ListNode*head) {
int cnt = 0;
int size = m;
ListNode* root = head->next;
int move = n%size;
while (size>0) {//还有节点在
if (root->exist == 1) cnt++;
if (cnt == move) {
cout << root->data << endl;
root->exist = 0;
size--;
cnt = 0;
}
root = root->next;
}
}
void show(ListNode* head) {
ListNode* ans = head->next;
head = head->next;
int t = 0;
while (t<10) {
t++;
cout << head->data<<endl;
head = head->next;
}
}
int main() {
int a = 0,b=0;
printf("请输入人数\n");
cin >> a;
printf("请输入循环次数\n");
cin >> b;
ListNode* head = build(a);
delete_say(a,b,head);
return 0;
}
5.单链表的数据的绝对值<m,删除绝对值一样的重复节点只保留第一个节点(用visit[]辅助数组)
#include<iostream>
#include<vector>
using namespace std;
vector<int>exist;
struct ListNode {
int data;
ListNode* next;
ListNode(int x) {
data = x;
next = NULL;
}
};
ListNode* build(int x) {
int a=0;//输入的元素
ListNode* head,*ans;//尾插法
head = new ListNode(-100);//dummy头,尾部节点连dummy的下一个,然后维护一个int记录
//链表的大小
ans = head;
while (x>0) {
x--;
cin >> a;
ListNode* cur = new ListNode(a);
head->next = cur;
head = head->next;
}
head->next = NULL;
return ans;
}
void show(ListNode* head) {
head = head->next;
while (head!=NULL) {
cout << head->data<<endl;
head = head->next;
}
}
ListNode* deletes(ListNode* head) {
ListNode *ans = head;
while (head->next!= NULL) {
int a = abs(head->next->data);
if (exist[a]) {
head->next = head->next->next;
// exist[a]--;
}
else {
exist[a]=1;
head = head->next;
}
}
return ans;
}
int main() {
int n,m;
cout << "请输入链表的个数"<<endl;
cin >> n;
cout << "请输入链表的data最大值" << endl;
cin >> m;
exist.resize(m,0);
//for(int i=0;i<exist.size();i++)
//cout <<exist[i]<<endl;
ListNode* head = build(n);
show(head);
head = deletes(head);
cout << "调用deletes(head)之后" << endl;
show(head);
return 0;
}
6.环状队列
#include<iostream>
#include<vector>
using namespace std;
int size_queue;
class queue {
public:
queue(int a) {
exist.resize(a + 1, 0);
front = 1;
rear = 1;
num = 0;
}
void push(int x) {
if (num == size_queue) {
cout << "队列满";
return;
}
num++;
exist[rear] = x;
rear++;
if (rear > size_queue)//保证求余后直接从1开始
rear %= size_queue;
}
void delete_element() {
if (num == 0) cout << "已经队空" << endl;
exist[front] = 0;
front++;
if(front>size_queue)//保证求余后直接从1开始
front %= size_queue;
num--;
}
void shuchu() {
for (int i = 0;i <= size_queue; i++) {
cout << exist[i] << " ";
}
cout << endl;
}
private:
vector<int>exist;
int front,rear,num;
};
int main() {
cout << "请输入数组的大小"<<endl;
cin >> size_queue;
queue q(size_queue);
int a;
cout << "输入1 push,输入2 pop,输入-1 end"<<endl;
cin >> a;
while (a!=-1) {
if (a == 1) {
int x;
cout << "输入要压进去的数";
cin >> x;
q.push(x);
}
else if (a == 2) {
q.delete_element();
}
q.shuchu();
cout << "输入1 push,输入2 pop,输入-1 end" << endl;
cin >> a;
}
}
7.双端队列
#include<iostream>
#include<vector>
using namespace std;
int item;
int size_queue;
class queue {
public:
queue(int a) {
exist.resize(a + 1, 0);
front = 1;
rear = 1;
num = 0;
}
void inject(int x) {
if (num == size_queue) {
cout << "队列满";
return;
}
num++;
exist[front] = x;
front++;
if (front > size_queue)//保证求余后直接从1开始
rear %= size_queue;
}
void push(int x) {
if (num == size_queue) {
cout << "队列满";
return;
}
num++;
exist[rear] = x;
rear++;
if (rear > size_queue)//保证求余后直接从1开始
rear %= size_queue;
}
void pop() {
if (num == 0) cout << "已经队空" << endl;
item = exist[front];
exist[front] = 0;
front++;
if(front>size_queue)//保证求余后直接从1开始
front %= size_queue;
num--;
}
void eject() {
if (num == 0) cout << "已经队空" << endl;
item = exist[rear];
exist[rear] = 0;
rear++;
if (rear > size_queue)//保证求余后直接从1开始
rear %= size_queue;
num--;
}
void shuchu() {
for (int i = 0;i <= size_queue; i++) {
cout << exist[i] << " ";
}
cout << endl;
}
private:
vector<int>exist;
int front,rear,num;
};
int main() {
cout << "请输入数组的大小"<<endl;
cin >> size_queue;
queue q(size_queue);
int a;
cout << "输入1 push,输入2 pop,输入-1 end"<<endl;
cin >> a;
while (a!=-1) {
if (a == 1) {
int x;
cout << "输入要压进去的数";
cin >> x;
q.push(x);
}
else if (a == 2) {
q.delete_element();
}
q.shuchu();
cout << "输入1 push,输入2 pop,输入-1 end" << endl;
cin >> a;
}
}
8.一数组,双栈迎面法
#include<iostream>
#include<vector>
using namespace std;
class stack {
public:
stack(int a) {
exist.resize(a, 0);
left = 0;
right = a - 1;
}
bool check() {
if (left == 0 && right == a - 1) return true;
return false;
}
void push1(int x) {
if (left < right) {
exist[left] = x;
left++;
}
else {
cout << "空间满啦";
}
}
void push2(int x) {
if (left < right) {
exist[right] = x;
right--;
}
else {
cout << "空间满啦";
}
}
void shuchu() {
for (int i = 0;i <exist.size(); i++) {
cout << exist[i] << " ";
}
cout << endl;
}
private:
vector<int>exist;
int left,right;
};
int main() {
}
9.用2栈实现队列
第九题在这:class MyQueue {
public:
stack<int>a1;//入队栈
stack<int>a2;//出队栈
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
a1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
if(!a2.empty()) {
int a=a2.top();
a2.pop();
return a;
}
while(!a1.empty()){//把a1的元素都变过去a2
int a=a1.top();
a1.pop();
a2.push(a);
}
if(!a2.empty()) {
int a=a2.top();
a2.pop();
return a;
}
return 0;
}
/** Get the front element. */
int peek() {
if(!a2.empty()) return a2.top();
while(!a1.empty()){//把a1的元素都变过去a2
int a=a1.top();
a1.pop();
a2.push(a);
}
if(!a2.empty()) return a2.top();
return 0;
}
/** Returns whether the queue is empty. */
bool empty() {
return a2.size()==0 && a1.size()==0;
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
11删除数组里的特定元素
`#include
#include
using namespace std;
//11题 双指针(赋值与探路指针法)(O(n))
int main() {
int n = 0;
cout << “请输入一下大小”;
cin >> n;
vectora(n, 0);
for (int i = 0; i <n ; i++) {
cin >> a[i];
}
int item;
cout << “请输入删除的元素”;
cin >> item;
int slow = 0, fast = 0;
while (fast < n) {
if (a[fast] == item) {
fast++;
}
else {
a[slow] = a[fast];
fast++;
slow++;
}
}
for (int i = 0; i <slow; i++) {
cout << a[i] << endl;
}
}
12:编写算法Reverse,将顺序存储的线性表A=( a1, a2, …, an )转换为A=( an,…, a2, a1),要求转换过程中用尽可能少的辅助空间。
算法:原地修改法
#include<iostream>
using namespace std;
int main() {
int b;
int a[100];
cin >> b;
for (int i = 0; i < b; i++) {
cin >> a[i];
}
int left = 0, right = b - 1;
while (left < right) {
int temp = a[left];
a[left] = a[right];
a[right] = temp;
left++;
right--;
}
for (int i = 0; i < b; i++) {
cout << a[i] << endl;
}
}
对于顺序栈和链式栈s,分别编写算法SelectItem,要求在堆栈中查找元素n在栈中第一次出现的位置,并将该位置元素移至栈顶,同时其他元素次序不变。
在这里插入代码片