# 啊哈！算法 案例用c++实现

#include<iostream>

using namespace std;

struct  stack
{
int top;//下一个应该放的元素位置
int mCapacity;
int *p;
stack(int capacity)
{
mCapacity = capacity;
p = new int[mCapacity];
top = 0;
}

int pop()
{
if (top==0)
{
cout << "栈是空的" << endl;
}
else
{
top--;//默认下一个位置就是待插入元素就可以了，并没有实际删除
return  p[top];
}
return -1;
}

int push(int x)
{
int ret = -1;
if (top>=mCapacity)
{
cout << "已经满了" << endl;

}
else
{
p[top] = x;
top++;
ret = x;

}
return ret;
}

int gettop()
{
if (top==0)
{
return -1;
}
else
{
return p[top-1];
}

}

int getsize()
{
}
};
int main()
{

stack s(5);
/*for (int i=0;i<5;i++)
{
s.push(i);

cout << "size()="<<  s.getsize() << endl;
}

for (int i = 0;i <10;i++)
{

cout << "pop()=" << s.pop() << endl;
}*/
//cout << "size()=" << s.getsize() << endl;

for (int i =3;i < 5;i++)
{
s.push(i);
cout << "gettop()=" << s.gettop() << endl;
//cout << "size()=" << s.getsize() << endl;
}

}


#include<iostream>

using namespace std;

//只能实现头插法，才能用链表
struct Node
{
int data;
Node *next;
Node()
{
data = 0;
next = nullptr;
}

Node(int x)
{
data =x;
next = nullptr;
}
};

struct linStack
{
Node * dummpy;

linStack()
{
dummpy = new Node();

}

int pop()
{
if (dummpy->next==NULL)//只有一个空节点，
{
cout << "栈现在是空的" << endl;
return -1;

}
else//注意一定要采用头插法
{
int ret = dummpy->next->data;

dummpy->next = dummpy->next->next;

return ret;
}

}

int push(int x)
{

Node * newnode = new Node(x);
newnode->next = dummpy->next;
dummpy->next = newnode;

return -1;
}

int getTop()
{
if (dummpy->next!=nullptr)
{
return dummpy->next->data;
}
else
{
return -1;
}

}

int getsize()
{

Node * p = dummpy->next;
int count = 0;
while (p != nullptr)
{
count++;
p = p->next;
}

return count;
}

};

int main()
{
linStack s;

for (int i=0;i<5;i++)
{
s.push(i);

//cout << "getsize=" << s.getsize() << endl;
}

for (int i = 0;i < 10;i++)
{

cout << "pop()=" << s.pop() << endl;
}

for (int i = 3;i < 10;i++)
{
s.push(i);
cout << "s.top()=" << s.getTop() << endl;
}

}


#include<iostream>
#include<algorithm>
using namespace std;

struct quque
{
int mCapacity;
int *p;
int tail;

quque(int capacity)
{
mCapacity = capacity;
p = new int[mCapacity];
tail = 0;//top是代表下一个位置需要插入的数
}

int front()
{
int size = abs(tail - head);
if (size == 0) return -1;
}

int  push(int x)
{

{
return -1;
}
else
{
p[tail] = x;

tail = (tail + 1) % mCapacity;
return 1;
}
}

int pop()
{

{
return -1;
}
else
{
int ret = front();
return ret;
}
}

int getsize()
{

}
};

int main()
{
quque  qu(5);

for (int i=0;i<5;i++)
{
qu.push(i);
}
cout << qu.getsize() << endl;;

int n = qu.getsize();
for (int i = 0;i < 100;i++)
{
cout << "qu.getsize()=" << qu.getsize() << endl;

int front = qu.pop();

cout << front << endl;

}

}


#include<iostream>
using namespace std;

struct Node
{
int data;
struct Node *next;
Node()
{
data = 0;
next = nullptr;
}

Node(int x)
{
data = x;
next = nullptr;
}
};

struct  queue
{
queue()
{
cout << "...构造函数" << endl;
}
};

int push(queue  &que,int x)
{
Node * newNode = new Node(x);

que.tail->next = newNode;
que.tail = que.tail->next;
return -1;

}

int pop(queue  &que)
{
int ret = -1;

//cout << que.head->data << "    " << que.tail->data << endl;
{
{
}
else
{
}

}
else
{
cout << "我们发现相等啊" << endl;
}
return ret;
}

int getsize(queue  que)
{
int size = 0;
while (p!=NULL)
{
p = p->next;
size++;
}
return size;
}

int main()
{
queue  qu;

for (int i=0;i<5;i++)
{
push(qu, i);
//cout << "getsize()=" << getsize(qu) << endl;
}

for (int i = 0;i < 10;i++)
{
cout << "pop=" << pop(qu) << endl;
}



#include<iostream>
#include<vector>
#include<queue>
using namespace std;

class Solution {
public:
vector<int> deCode(vector<int>& nums) {

vector<int> ret_v;
queue<int> qu;
for (int i=0;i<nums.size();i++)
{
qu.push(nums[i]);
}
while (!qu.empty())
{
//将删除的元素放到 ret中
ret_v.push_back(qu.front());
qu.pop();
if (!qu.empty())
{

// 然后将元素放到队列的尾端
int front = qu.front();
qu.pop();

qu.push(front);
}

}

return ret_v;
}
};

int main()
{
vector<int> nums{ 6,3 ,1,7,5,8,9,2,4 };
Solution s;
vector<int> ret_v=s.deCode(nums);

for (auto one: ret_v)
{
cout << one << "  ";
}
}


#include<iostream>
#include<vector>
#include<queue>
using namespace std;

class Solution {

private:
{
int front = qu.front();
qu.pop();

auto it = find(restore.begin(), restore.end(), front);

if (it != restore.end())
{
vector<int> append_v;
append_v.push_back(front);//拖拉机里面的第一个数就是我们的front
//需要弹出 将其补到restore的尾端

int j = int(restore.size()) - 1;//避免无符号转换
while (j >= 0 && restore[j] != front)//这里肯定能找到 restore[j]
{

append_v.push_back(restore[j]);
restore.pop_back();//这个千万不要忘记
j--;//不要忘记了
}
append_v.push_back(restore[j]);//这个是最后一个
restore.pop_back();

for (int val : append_v)
{
qu.push(val);
}
}
else
{//直接加入到restore中
restore.push_back(front);
}
}
public:
/*
返回true代表nums1会赢  否则false
*/
bool doTractor(vector<int>& nums1,vector<int>& nums2)
{

vector<int> restore;

queue<int> qu1;
for (auto value : nums1) qu1.push(value);

queue<int> qu2;
for (auto value : nums2) qu2.push(value);

while (!qu1.empty()&&!qu2.empty())
{
cout << "qu1.size()=" << qu1.size() << "   qu2.size()=" << qu2.size() << "  restore.size()=" << restore.size() << endl;

if (qu1.empty()) break;

if (qu2.empty()) break;
}

cout << "结果返回值" << endl;
cout << "qu1.size()=" << qu1.size() << "   qu2.size()=" << qu2.size() << "  restore.size()=" << restore.size() << endl;

if (!qu1.empty())
{
cout << "小哼赢了" << endl;
while (!qu1.empty())
{
cout << "  " << qu1.front();
qu1.pop();
}
cout << endl;
cout << "桌子上面的牌" << endl;

for (int val:restore)
{
cout << "  " << val;
}

cout << endl;
return true;
}
else
{
cout << "小哈赢了" << endl;
while (!qu2.empty())
{
cout << "  " << qu2.front();
qu2.pop();
}
cout << endl;

cout << "桌子上面的牌" << endl;

for (int val : restore)
{
cout << "  " << val;
}
cout << endl;
return false;
}

}
};

int main()
{
vector<int> nums1{ 2,4,1,2,5,6 };
vector<int> nums2{3,1,3,5,6,4};

Solution s;
bool ret_b = s.doTractor(nums1, nums2);

//cout << ret_b << endl;
}


leetcode题目链接

46. 全排列

[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

dfs的思想，这里的index并不代表元素的下标，只是代表元素的个素，我习惯在dfs里面用index表示递归的深度。

class Solution {
private:
vector<vector<int>> ret_vv;

void dfs(vector<int>& nums,vector<bool>& used,vector<int>& temp,int index)
{
if(index>=nums.size())
{
ret_vv.push_back(temp);
return;
}

for(int i=0;i<nums.size();i++)
{
if(used[i]==true) continue;

temp.push_back(nums[i]);
used[i]=true;

dfs(nums,used,temp,index+1);
temp.pop_back();
used[i]=false;
}
}
public:
vector<vector<int>> permute(vector<int>& nums)
{
vector<bool> used(nums.size(),false);
vector<int > temp;
int index=0;
dfs(nums,used,temp,index);
return ret_vv;

}
};


leetcode题目链接
47. 全排列 II

[[1,1,2],
[1,2,1],
[2,1,1]]

 if(i>0&&nums[i]==nums[i-1]&&isUse_v[i-1]==false) continue;


 if(i>0&&nums[i]==nums[i-1]&&isUse_v[i-1]==true) continue;


class Solution {
private:

void dfs(int index,vector<int>& nums,vector<bool> &isUse_v,vector<vector<int>> &result_vv,vector<int>&temp_v)
{
if(index>=nums.size())
{
result_vv.push_back(temp_v);
return;
}

for(int i=0;i<nums.size();i++)
{
if(isUse_v[i]==true)  continue;
if(i>0&&nums[i]==nums[i-1]&&isUse_v[i-1]==false) continue;

temp_v.push_back(nums[i]);
isUse_v[i]=true;

dfs(index+1,nums,isUse_v,result_vv,temp_v);

isUse_v[i]=false;
temp_v.pop_back();

}
}

public:
vector<vector<int>> permuteUnique(vector<int>& nums) {

vector<vector<int>>result_vv;
vector<int>temp_v;
vector<bool> isUse_v(nums.size(),false);
sort(nums.begin(), nums.end());
dfs(0,nums,isUse_v,result_vv,temp_v);

return result_vv;
}
};


dfs 上面题目3.1已经写过了。

class Solution {
private:

void dfs(int index,vector<int>& nums,vector<bool> &isUse_v,vector<vector<int>> &result_vv,vector<int>&temp_v)
{
if(index>=nums.size())
{
result_vv.push_back(temp_v);
return;
}

for(int i=0;i<nums.size();i++)
{
if(isUse_v[i]==true)  continue;
if(i>0&&nums[i]==nums[i-1]&&isUse_v[i-1]==false) continue;

temp_v.push_back(nums[i]);
isUse_v[i]=true;

dfs(index+1,nums,isUse_v,result_vv,temp_v);

isUse_v[i]=false;
temp_v.pop_back();

}
}

public:
vector<vector<int>> permuteUnique(vector<int>& nums) {

vector<vector<int>>result_vv;
vector<int>temp_v;
vector<bool> isUse_v(nums.size(),false);
sort(nums.begin(), nums.end());
dfs(0,nums,isUse_v,result_vv,temp_v);

return result_vv;
}
};


dfs，注意每次的递归终止条件是index>=nums.size()

A+B=C

#include<iostream>
#include<vector>
using namespace std;

class Solution {

private:
bool Compare(int temp)
{
//A+B=C;
int a[3];
int i = 0;
while (temp != 0)
{
a[i] = temp % 1000;
temp = temp / 1000;
i++;
}
//A+B==C?
if (a[2] + a[1] == a[0])
{
cout << a[2] << "+" << a[1] << "=" << a[0] << endl;
return true;
}
else return false;

}

void dfs(vector<int>& nums, vector<bool>& used, int temp, int index )
{
if (index>= nums.size())
{
if (Compare(temp)) sum++;

return;
}

for (int i=0;i<nums.size();i++)
{
if (used[i] == true) continue;

used[i] = true;

dfs(nums, used, temp * 10 + nums[i], index+1);//千万要注意我们没有传 temp引用，ndex引用
used[i] = false;
}
}
int sum = 0;
public:
int  permuteSumDiff(vector<int>& nums)
{
int temp = 0;//这个是存每次递归的和
int index = 0;

vector<bool>  used(nums.size(),false);//标志位
dfs(nums, used, temp,index );

return sum;

}
};
int main()
{
vector<int> numbers{ 1,2,3,4,5,6,7,8,9 };
Solution s;
int sum=s.permuteSumDiff(numbers);

cout << "sum=" << sum << endl;

}



#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Solution {
private:
int global_step = INT_MAX;

vector<vector<int>> dxy{ {0,1},{1,0},{0,-1}, {-1,0}};//走的方向依次是  右下左上
bool isArea(vector<vector<int>> &maze,int temp_x,int temp_y)
{
if (temp_x < 0 || temp_x >= maze.size() || temp_y < 0 || temp_y >= maze[0].size())  return false;

return true;

}

void dfs(vector<vector<int>> &maze, vector<vector<bool>> &used,int current_i, int current_j, int target_i, int target_j, int &step)
{

if (current_i == target_i&& current_j == target_j)
{
global_step = min(global_step,step);
return;
}

for (int i=0;i < dxy.size();i++)
{
int temp_i = current_i + dxy[i][0];
int temp_j = current_j + dxy[i][1];

if (isArea(maze, temp_i, temp_j) && maze[temp_i][temp_j] == 0 &&used[temp_i][temp_j] == false)
{
used[temp_i][temp_j] = true;
step++;

dfs(maze, used, temp_i, temp_j, target_i, target_j, step);

step--;
used[temp_i][temp_j] = false;
}
}
}

public:
int getShortpath(vector<vector<int>> &maze, int start_i, int start_j, int target_i, int target_j)  //maze中0代表可走，1代表是障碍物
{
vector<vector<bool>> used(maze.size(), vector<bool>(maze[0].size(), false));

if (isArea(maze, start_i, start_j) && used[start_i][start_j] == false)//这里防止刚开始位置越界
{

used[start_i][start_j] = true;
int step = 0;
dfs(maze, used, start_i,  start_j, target_i,  target_j, step);

}

return global_step;
}
};

int main()
{

vector<vector<int>>  maze{
{0,0,1,0},
{0,0,0,0},
{0,0,1,0},
{0,1,0,0},
{0,0,0,1} };
int start_i = 0;
int start_j = 0;
int target_i = 3;
int target_j = 2;
Solution s;
int path=s.getShortpath(maze, start_i, start_j, target_i, target_j);
cout << "path=" << path << endl;
}



#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Solution {
private:

vector<vector<int>> dxy{ {0,1},{1,0},{0,-1}, {-1,0} };//走的方向依次是  右下左上
bool isArea(vector<vector<int>> &maze, int temp_x, int temp_y)
{
if (temp_x < 0 || temp_x >= maze.size() || temp_y < 0 || temp_y >= maze[0].size())  return false;

return true;

}

public:
int getShortpath(vector<vector<int>> &maze, int start_i, int start_j, int target_i, int target_j)  //maze中0代表可走，1代表是障碍物
{
vector<vector<bool>> used(maze.size(), vector<bool>(maze[0].size(), false));

if (isArea(maze, start_i, start_j) && used[start_i][start_j] == false)//这里防止刚开始位置越界
{

used[start_i][start_j] = true;

int step = 0;
queue<pair<int, int>> qu;
qu.emplace(start_i, start_j);

while (!qu.empty())
{

int n = qu.size();
for (int i=0;i<n;i++)
{
auto node = qu.front();
qu.pop();//一定记得pop
int current_i = node.first;
int current_j = node.second;
//cout << "current_i=" << current_i << "  current_j=" << current_j  << "  step="<< step << endl;
if (current_i == target_i && current_j == target_j)
{

return  step;
}

for (int i = 0;i < dxy.size();i++)
{

int temp_i = current_i + dxy[i][0];
int temp_j = current_j + dxy[i][1];

if (isArea(maze, temp_i, temp_j) &&maze[temp_i][temp_j]==0&& used[temp_i][temp_j] == false)
{
cout << "temp_i=" << temp_i << "  temp_j=" << temp_j << "  step=" << step << endl;
used[temp_i][temp_j] = true;

qu.emplace(temp_i, temp_j);

}

}

}
cout << "*******************" << endl;
for (int i=0;i<used.size();i++)
{
for (int j = 0;j<used[0].size();j++)
{
cout << used[i][j] << "  ";
}
cout << endl;

}
cout << endl;
cout << "*******************" << endl;
step++;

}

}

return INT_MAX;
}
};

int main()
{
vector<vector<int>>  maze
{
{0,0,1,0},
{0,0,0,0},
{0,0,1,0},
{0,1,0,0},
{0,0,0,1} };
int start_i = 0;
int start_j = 0;
int target_i = 3;
int target_j = 2;
Solution s;
int path = s.getShortpath(maze, start_i, start_j, target_i, target_j);
cout << "path=" << path << endl;

}


floodfilld应用

#include<iostream>
#include<vector>

using namespace std;

class Solution {

private:
vector<vector<int>> dxy{ {0,1},{1,0},{0,-1}, {-1,0} };//走的方向依次是  右下左上

bool  isArea(vector<vector<int>>& grid, int temp_i, int temp_j)
{
if (temp_i < 0 || temp_i >= grid.size() || temp_j < 0 || temp_j >= grid[0].size())  return false;

return true;
}

int s = 0;//这个是可以这样进行赋值的

void dfs(vector<vector<int>>&grid, vector<vector<bool>>& used, int current_i, int current_j)
{

for (int i = 0;i < dxy.size();i++)
{
int temp_i = current_i + dxy[i][0];
int temp_j = current_j + dxy[i][1];

if (isArea(grid, temp_i, temp_j) && grid[temp_i][temp_j] > 0 && used[temp_i][temp_j] == false)
{
used[temp_i][temp_j] = true;

s++;
grid[temp_i][temp_j] = s;
dfs(grid, used, temp_i, temp_j);

//used[temp_i][temp_j] = false;  floodfill 就是不要这句话
}
}
}
public:
int islandArea(vector<vector<int>>& grid,int start_i,int start_j)
{

vector<vector<bool>> used(grid.size(), vector<bool>(grid[0].size(), false));
if (isArea(grid,start_i,start_j)&&used[start_i][start_j]==false)
{
if (grid[start_i][start_j] > 0)
{
used[start_i][start_j] = true;

s++;
grid[start_i][start_j] = s;
dfs(grid, used, start_i, start_j);
}

}

cout << "*******************" << endl;
for (int i = 0;i < grid.size();i++)
{
for (int j = 0;j < grid[0].size();j++)
{
//cout << grid[i][j] << "     ";
printf("%5d", grid[i][j]);
}
cout << endl;

}
cout << endl;
cout << "*******************" << endl;

return s;
}
};

int main()
{

vector<vector<int>>  maze{
{1,2,1,0,0,0,0,0,2,3},
{3,0,2,0,1,2,1,0,1,2},
{4,0,1,0,1,2,3,2,0,1},
{3,2,0,0,0,1,2,4,0,0},
{0,0,0,0,0,0,1,5,3,0},
{0,1,2,1,0,1,5,4,3,0},
{0,1,2,3,1,3,6,2,1,0},
{0,0,3,4,8,9,7,5,0,0},
{0,0,0,3,7,8,6,0,1,2},
{0,0,0,0,0,0,0,0,1,0},
};
int start_i = 5;
int start_j = 7;

Solution s;
int sum = s.islandArea(maze, start_i, start_j);

cout << "sum=" << sum << endl;
}



leetcode200. 岛屿数量

floodfill，相比较题目4.6而言，需要在main函数中套上循环遍历grid



class Solution {

private:
vector<vector<int>> dxy{ {0,1},{1,0},{0,-1}, {-1,0} };//走的方向依次是  右下左上

bool  isArea(vector<vector<char>>& grid, int temp_i, int temp_j)
{
if (temp_i < 0 || temp_i >= grid.size() || temp_j < 0 || temp_j >= grid[0].size())  return false;

return true;
}

int count = 0;//这个是可以这样进行赋值的

void dfs(vector<vector<char>>&grid, vector<vector<bool>>& used, int current_i, int current_j)
{

for (int i = 0;i < dxy.size();i++)
{
int temp_i = current_i + dxy[i][0];
int temp_j = current_j + dxy[i][1];

if (isArea(grid, temp_i, temp_j) && grid[temp_i][temp_j] !='0' && used[temp_i][temp_j] == false)
{
used[temp_i][temp_j] = true;

dfs(grid, used, temp_i, temp_j);

//used[temp_i][temp_j] = false;  floodfill 就是不要这句话
}
}
}
public:
int numIslands(vector<vector<char>>& grid)
{

vector<vector<bool>> used(grid.size(), vector<bool>(grid[0].size(), false));

for (int start_i=0;start_i<grid.size();start_i++)
{
for (int start_j = 0;start_j < grid[0].size();start_j++)
{

if (isArea(grid, start_i, start_j) && used[start_i][start_j] == false)
{
if (grid[start_i][start_j] != '0')
{
used[start_i][start_j] = true;

count++;

dfs(grid, used, start_i, start_j);
}

}

}
}

return count;
}
};



6.1.1方法一：广度优先搜索算法
//bfs寻路算法 确定也明显 没有像 迪杰斯特拉算法中的最短路径一样。也就是没有权值不能找到最短的

//bfs寻路算法  确定也明显 没有像 迪杰斯特拉算法中的最短路径一样。也就是没有权值，不能找到最短的

//used[temp_i][temp_j] = true;  bfs没有对应的 false这是和bfs不一样的
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Solution {
private:

vector<vector<int>> dxy{ {0,1},{1,0},{0,-1}, {-1,0} };//走的方向依次是  右下左上
bool isArea(vector<vector<int>> &maze, int temp_x, int temp_y)
{
if (temp_x < 0 || temp_x >= maze.size() || temp_y < 0 || temp_y >= maze[0].size())  return false;

return true;

}

public:
int getShortpath(vector<vector<int>> &maze, int start_i, int start_j, int target_i, int target_j)  //maze中0代表可走，1代表是障碍物
{
vector<vector<bool>> used(maze.size(), vector<bool>(maze[0].size(), false));

if (isArea(maze, start_i, start_j) && used[start_i][start_j] == false)//这里防止刚开始位置越界
{

used[start_i][start_j] = true;

int step = 0;
queue<pair<int, int>> qu;
qu.emplace(start_i, start_j);

while (!qu.empty())
{

int n = qu.size();
for (int i = 0;i < n;i++)
{
auto node = qu.front();
qu.pop();//一定记得pop
int current_i = node.first;
int current_j = node.second;
//cout << "current_i=" << current_i << "  current_j=" << current_j  << "  step="<< step << endl;
if (current_i == target_i && current_j == target_j)
{

return  step;
}

for (int i = 0;i < dxy.size();i++)
{

int temp_i = current_i + dxy[i][0];
int temp_j = current_j + dxy[i][1];

if (isArea(maze, temp_i, temp_j) && maze[temp_i][temp_j] == 0 && used[temp_i][temp_j] == false)
{
cout << "temp_i=" << temp_i << "  temp_j=" << temp_j << "  step=" << step << endl;
used[temp_i][temp_j] = true;

qu.emplace(temp_i, temp_j);

}

}

}
cout << "*******************" << endl;
for (int i = 0;i < used.size();i++)
{
for (int j = 0;j < used[0].size();j++)
{
cout << used[i][j] << "  ";
}
cout << endl;

}
cout << endl;
cout << "*******************" << endl;
step++;

}

}

return INT_MAX;
}
};

int main()
{
vector<vector<int>>  maze
{
{0,0,1,0},
{0,0,0,0},
{0,0,1,0},
{0,1,0,0},
{0,0,0,1} };
int start_i = 0;
int start_j = 0;
int target_i = 3;
int target_j = 2;
Solution s;
int path = s.getShortpath(maze, start_i, start_j, target_i, target_j);
cout << "path=" << path << endl;

}


6.1.2迪杰斯特拉算法 可以找到所有的节点最短路径，

		vector<int> visit(n,0);//0代表未访问节点，1代表访问节点

vector<int> dist(n, 0);//后面会根据start进行初始化，这里初始化值是任何值都没关系



//单源最短路径，迪杰斯特拉算法

//总体思路，是将每次最短的还没有访问的节点作为中转节点，然后从寻找从中转节点到其他节点和之前的到start的节点路径作比较，
//更新每个未访问节点的最短路径，将中转节点设置成访问节点，进入下一次循环。
#include<iostream>
#include<vector>

#define INF  999999//路径中不可达边  因此graph也应该这么写不可达边的长度

using namespace std;

class Solution {
public:
vector<int> Dijkstra(vector<vector<int>>& graph,int start)
{
int n = graph.size();
vector<int> visit(n,0);//0代表未访问节点，1代表访问节点

vector<int> dist(n, 0);//后面会根据start进行初始化，这里初始化值是任何值都没关系

//首先将第一个start节点的信息提取出来，为循环做出准备
if (start>=n)
{
cout << "起点位置不合法" << endl;
return  dist;
}
visit[start] = 1;//  设置起点位置已访问1
for (int i=0;i<n;i++)//设置起点位置为初始位置，初始化dist
{
dist[i] = graph[start][i];
}

for (int i=1;i<n;i++)//第一个节点已经单独拎出来了个节点，所以我们需要循环n-1次
{
int minNumber = INF;

int mind=1111;//我们从这里可以看出无论此处mind初始值是多少，如果不是连通图，可能会造成，死循环， 因此使用该算法的图应该是连通图

for (int j=0;j< dist.size();j++)//寻找中转节点  记住当前中转节点一定是未访问节点
{
if (visit[j]==0&& minNumber> dist[j])
{
minNumber = dist[j];
mind = j;
}
}

//cout << "mind=" << mind << endl;
//visit[mind] = 1;  //这个放在这里也是可以的

//中转节点找到后，我们需要更新当前以中转节点和原点的  到其他非访问节点距离
for (int j=0;j<n;j++)//这里的j代表着节点的下标的意思
{
if (visit[j]==0&&dist[j]>dist[mind]+graph[mind][j])//这一步说明了graph中不能有INT_MAX不然可能会溢出
{
dist[j] = dist[mind] + graph[mind][j];
}
}

visit[mind] = 1;//应该将中转节点设置成已访问
}

return dist;
}
};

int main()
{
int n = 6;
vector<vector<int>> graph(n, vector<int>(n, INF));

for (int i=0;i<n;i++)
{
graph[i][i] = 0;
}

graph[0][1] = 100;
graph[1][0] = 100;

graph[0][2] = 1200;
graph[2][0] = 1200;

graph[1][2] = 900;
graph[2][1] = 900;

graph[1][3] = 300;
graph[3][1] = 300;

graph[2][3] = 400;
graph[3][2] = 400;

graph[2][4] = 500;
graph[4][2] = 500;

graph[3][4] = 1300;
graph[4][3] = 1300;

graph[3][5] = 1400;
graph[5][3] = 1400;

graph[4][5] = 1500;
graph[5][4] = 1500;

Solution s;
vector<int> dist;

for (int j=0;j<n;j++)
{
cout << "以索引值为start=" << j << "设置为起始点" << endl;
dist = s.Dijkstra(graph, j);

for (int i = 0;i < n;i++)
{
cout << "  " << dist[i];
}
cout << endl;

}

}


6.1.3方式三：A*算法视频参考链接
**A*算法，**可以确定最短路径（总代价最小） 总代价=当前代价+预估代价

struce  cmp
{
operator()(node1,node2)
{

return node1.step_cost+node1.cost_so_far>node2.step_cost+node2.cost_so_far
}
]


leetcode排序链接

		vector<int> temp_v = nums;//进行堆排序输出

//大根堆建好后，开始进行堆顶元素
cout << "堆排序后的数组逻辑为" << endl;
for (int i=n-1;i>=0;i--)//这其实可以看做是一个删除的过程
{
swap(temp_v[0], temp_v[i]);
sortHeap(temp_v, 0, i);//每次将最后一个位置确定后，循环n次1，这样数组就是有序的

}


void pop(vector<int>& nums)
{
int n = nums.size();
swap(nums[0], nums[n - 1]);

cout << "删除的栈顶元素是" << nums.back() << endl;
nums.pop_back();

n = nums.size();//nums中已经删除一个元素了。因此需要重新取大小

sortHeap(nums, 0, n);

}


#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Solution {

private:
void sortHeap(vector<int>& nums,int index, int n)//我们需要建立大根堆
{
int max = index;
int left_index = index * 2 + 1;
int right_index = index * 2 + 2;

if (left_index<n&&nums[left_index]>nums[max])
{
max = left_index;
}

if (right_index<n&&nums[right_index]>nums[max])
{
max = right_index;
}

if (max != index)
{
swap(nums[max],nums[index]);

sortHeap(nums, max, n);//这是一个下溯的过程
}
}
public:
vector<int> Heap(vector<int>& nums) {

int n = nums.size();
for (int index=n/2-1;index >=0;index--)  //index代表着我们的需要比对的初始化的数字的位置（上溯过程）
{

sortHeap(nums, index, n);
}

vector<int> temp_v = nums;//进行堆排序输出

//大根堆建好后，开始进行堆顶元素
cout << "堆排序后的数组逻辑为" << endl;
for (int i=n-1;i>=0;i--)//这其实可以看做是一个删除的过程
{
swap(temp_v[0], temp_v[i]);
sortHeap(temp_v, 0, i);//每次将最后一个位置确定后，循环n次1，这样数组就是有序的

}

//cout << endl;
return temp_v;
}

//插入
void insert(vector<int>& nums,int x)
{
nums.push_back(x);

int n = nums.size();
for (int index = n / 2 - 1;index >= 0;index--)  //index代表着我们的需要比对的初始化的数字的位置（上溯过程）
{

sortHeap(nums, index, n);
}

}

//删除元素
void pop(vector<int>& nums)
{
int n = nums.size();
swap(nums[0], nums[n - 1]);

cout << "删除的栈顶元素是" << nums.back() << endl;
nums.pop_back();

n = nums.size();//nums中已经删除一个元素了。因此需要重新取大小

sortHeap(nums, 0, n);

}

};

int main()
{

vector<int> nums{ 4,6,2,3,5,8,6,9,4,1,6 };

Solution s;
vector<int> ret=s.Heap(nums);

for (int value:ret)
{
cout << "   " << value;
}
cout << endl;

int n = nums.size();

for (int i=0;i<n;i++)
{
s.pop(nums);
}

s.insert(nums,5);
s.insert(nums,4);
s.insert(nums,10);
n = nums.size();
cout << "插入元素后重新删除" << endl;
for (int i = 0;i < n;i++)
{
s.pop(nums);
}
}


leetcode 684链接


#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;

const int MAXN = 1e6 + 10;
int parent[MAXN], RANK[MAXN];

void Init()
{
for (int i=0;i< MAXN;i++)
{
parent[i] = i;
RANK[i] = 1;
}
}
//寻找x的头部(非递归写法)
int  Find(int x)
{
int x_root = x;
while (parent[x_root]!= x_root)
{
x_root = parent[x_root];
}
return x_root;
}

//int  Find(int x)
//{
//
//	if (parent[x] == x)
//	{
//		return x;
//	}
//	return Find(parent[x]);
//}

int Union(int u, int v)
{
u = Find(u);
v = Find(v);
if (u != v)
{
if (RANK[u] > RANK[v] )
{
parent[v] = u;
}
else if(RANK[v] > RANK[u])
{
parent[u] = v;
}
else if (RANK[v]= RANK[u])
{
parent[v] = u;
RANK[u]++;
}

return 1;
}
else
{
return 0;
}

}
int main()
{
Init();
vector<vector<int>> vv{
{0,1},{1,2},{1,3},
{2,5},{2,4},{3,4}
};
for (int i=0;i< vv.size();i++)
{
int u = vv[i][0];
int v = vv[i][1];

if (Union(u, v) == 0)
{
cout << " 图中存在环" << endl;
return 0;
}
}
cout << " 图中不存在环" << endl;
return 1;
}


• 0
点赞
• 0
评论
• 1
收藏
• 一键三连
• 扫一扫，分享海报

07-17

08-30 103
08-09 220
12-03
10-27 479
01-02 1268
04-17
10-26 847
06-08
04-14 344
10-29 610
10-28 603
08-19 1531