数据结构:
1、顺序表
#include<iostream>
#include<string>
using namespace std;
#define MAX_SIZE 100
typedef struct
{
int* elems; //顺序表的地址
int length; //顺序表的长度,实际元素的个数
int size; //顺序表的空间
}SqList;
//初始化顺序表
bool initList(SqList& L) //构造一个空的顺序表L
{
L.elems = new int[MAX_SIZE];
if (!L.elems) return false;
L.length = 0;
L.size = MAX_SIZE;
return true;
}
//添加元素
bool listAppend(SqList& L,int e)
{
if (L.length == L.size) return false;
L.elems[L.length] = e;
L.length++;
return true;
}
//插入元素
bool listInsert(SqList& L, int i, int e)
{
if (i < 0 || i >= L.length) return false;
if (L.length == L.size) return false;
for (int j = L.length - 1; j >= i; j--)
{
L.elems[j + 1] = L.elems[j];
}
L.elems[i] = e;
L.length++;
return true;
}
//删除元素
bool listDelete(SqList& L, int i)
{
if (i < 0 || i >= L.length) return false;
if (i == L.length - 1)
{
L.length--;
return true;
}
for (int j = i; j < L.length - 1; ++j)
{
L.elems[j] = L.elems[j+1];
}
L.length--;
return true;
}
//打印顺序表
void ListPrint(SqList& L)
{
cout << "顺序表存储空间size: " << L.size << ", 已保存的元素length:" << L.length << endl;
for (int i = 0; i < L.length; ++i)
{
cout << L.elems[i] << " ";
}
cout << endl;
}
//销毁顺序表
void destoryList(SqList& L)
{
if (L.elems) delete[] L.elems;
L.length = 0;
L.size = 0;
}
int main()
{
SqList list;
int i,e;
cout << "顺序表的初始化:" << endl;
if (initList(list))
{
cout << "顺序表初始化成功" << endl;
}
ListPrint(list);
//添加元素
int count = 0;
cout << "请输入要添加的元素的个数:";
cin >> count;
for (int i = 0; i < count; i++)
{
cout << "\n请输入要添加的元素e: ";
cin >> e;
if (listAppend(list, e))
{
cout << "添加成功!" << endl;
}
else
{
cout << "添加失败!" << endl;
}
}
ListPrint(list);
//插入元素
cout << "要插入的元素的位置和元素:";
cin >> i >> e;
if (listInsert(list, i, e))
{
cout << "插入成功!" << endl;
}
else
{
cout << "插入失败!" << endl;
}
ListPrint(list);
//删除元素
cout << "请输入要删除的位置:";
cin >> i;
if (listDelete(list, i))
{
cout << "删除成功!" << endl;
}
else
{
cout << "删除失败!" << endl;
}
ListPrint(list);
//销毁顺序表
cout << "销毁顺序表:";
destoryList(list);
system("pause");
return 0;
}
2、单链表
#include<iostream>
#include<string>
using namespace std;
typedef struct _LinkNode
{
int data; //节点数据域
struct _LinkNode *next; //节点指针域
}LinkNode,LinkList; //链表节点,链表
//初始化空链表
bool InitList(LinkList* &L)
{
L = new LinkNode;
if (!L) return false;
L->next = NULL;
L->data = -1;
return true;
}
//前插法
bool ListInsert_front(LinkList*& L, LinkNode* node)
{
if (!L || !node) return false;
node->next = L->next;
L->next = node;
return true;
}
//尾插法
bool ListInsert_back(LinkList* &L, LinkNode* node)
{
LinkList* last = NULL;
if (!L || !node) return false;
last = L;
while (last->next) last = last->next;
node->next = NULL;
last->next=node;
return true;
}
//指定位置插入元素
bool ListInsert(LinkList* &L, int i, int& e)
{
int j = 0;
if (!L) return false;
LinkList *p, *s;
p = L;
while (p && j < i - 1) //查找位置为i-1的节点,p指向该节点
{
p = p->next;
++j;
}
if (!p || j > i - 1) return false; //i为负数或者为0,不符合插入要求 ,有点蒙蔽
s = new LinkNode;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//打印单链表
void LinkPrint(LinkList* &L)
{
LinkNode* p = NULL;
if (!L)
{
cout << "链表为空!" << endl;
return;
}
p= L->next;
while (p)
{
cout << p->data << "\t";
p = p->next;
}
cout << endl;
}
//获取值
bool Link_GetElem(LinkList* &L, int i, int &e) //单链表的取值
{
int index;
LinkList* p;
if (!L || !L->next) return false;
p = L->next;
index = 1;
while (p && index < i)
{
p = p->next;
index++;
}
if (!p || index > i)
{
return false;
}
e = p->data;
return true;
}
//按值查找
bool Link_FindElem(LinkList* &L, int e, int &index)
{
LinkList* p;
p = L->next;
index = 1;
if (!L || !L->next)
{
return false;
index = 0;
}
while (p && p->data!= e)
{
p = p->next;
index++;
}
if (!p) //查无此值
{
return false;
index = 0;
}
return true;
}
// 单链表删除元素
bool LinkDelete(LinkList* &L, int i)
{
LinkList* p, * q;
int index = 0;
p = L;
if (!L || !L->next)
{
return false;
}
while ((p->next) && (index < i - 1))
{
p = p->next;
index++;
}
if ((!p->next) || (index > i - 1)) //当i>n 或 i<1时,删除位置不合适
{
return false;
}
q = p->next; //临时保存被删除的节点的地址以备释放空间
p->next = q->next; //改变删除节点前驱节点的指针域
delete q; //释放删除节点的空间
return true;
}
//销毁单链表
void LinkDestroy(LinkList* &L)
{
LinkList* p = L; //定义临时节点p指向头结点
cout << "销毁链表!" << endl;
while (p)
{
L = L->next;
cout << "删除元素: " << p->data << endl; //L指向下一个节点
delete p; //删除当前节点
p = L; //p移向下一个节点
}
}
int main()
{
LinkList* L = NULL;
LinkNode* s = NULL;
//初始化空链表
InitList(L);
//使用前插法插入数据
int n;
cout << "请输入元素个数n: ";
cin >> n;
while (n >0)
{
s = new LinkNode;
cin >> s->data;
ListInsert_front(L, s);
n--;
}
LinkPrint(L);
//使用尾插法
int n;
cout << "请输入元素个数n: ";
cin >> n;
while (n > 0)
{
s = new LinkNode;
cin >> s->data;
ListInsert_back(L, s);
n--;
}
LinkPrint(L);
//任意位置插入元素
for (int j = 0; j < 3; ++j)
{
cout << "开始任意位置插入表演:" << endl;
int i, x;
cin >> i;
cin >> x;
if (ListInsert(L, i, x))
{
cout << "任意位置插入成功!" << endl;
}
else
{
cout << "任意位置插入失败!" << endl;
}
LinkPrint(L);
}
//取值
int element = 0;
if (Link_GetElem(L, 2, element))
{
cout << "获取第二个元素成功,值: " << element << endl;
}
else
{
cout << "获取第二个元素失败!" << endl;
}
//按值查找
int index = 0;
if (Link_FindElem(L, 10, index))
{
cout << "查找元素10存在,所在位置: " << index << endl;
}
else
{
cout << "元素不存在 10" << endl;
}
// 单链表删除元素
if (LinkDelete(L, 2))
{
cout << "删除第二个元素成功!" << endl;
LinkPrint(L);
}
else
{
cout << "删除第二个元素失败!" << endl;
}
//销毁链表
LinkDestroy(L);
system("pause");
return 0;
}
3、循环链表
#include<iostream>
#include<string>
using namespace std;
typedef struct _LinkNode
{
int data; //节点数据域
struct _LinkNode* next; //节点指针域
}LinkNode, LinkList; //链表节点,链表
//构造空的循环链表
bool InitList(LinkList* &L)
{
L = new LinkNode;
if (!L) return false;
L->next =L;
L->data = -1;
return true;
}
//尾插法
bool ListInsert_back(LinkList* &L, LinkList *node)
{
LinkList* last = NULL;
if (!L || !node) return false;
if (L == L->next) //头结点的指针域指向了自己,也就是空的循环链表
{
node->next = L;
L->next = node;
}
else //非空的循环链表
{
last = L;
while (last->next !=L) last = last->next; //定位last尾节点
node->next = L;
last->next = node;
}
return true;
}
//打印循环链表
void LinkPrint(LinkList* L)
{
LinkList* p;
if (!L || L == L->next)
{
cout << "链表为空!" << endl;
return;
}
p = L->next;
while (p != L)
{
cout << p->data << "\t";
p = p->next;
}
cout << endl;
}
bool Joseph(LinkList* &L, int interval)
{
LinkList* p, *q;
int i = 0;
int j = 0;
int times = 0;
int num = 0;
p = L;
if (!L || p->next == L)
{
cout << "链表为空!" << endl;
return false;
}
if (interval < 1)
{
cout << "报数淘汰口令不能小于1" << endl;
return false;
}
do
{
i = i + interval;
while (p->next)
{
if (p->next != L) j++;
if (j >= i) break;
p = p->next;
}
times++;
q = p->next;
if (q != nullptr)
{
num = q->data;
}
else
{
exit(-1);
}
if (times == 5)
{
cout << "第五个出圈的编号为:"<<num << endl;
}
printf("cur: %d last: %d next:%d\n", q->data, p->data,q->next->data);
p->next = q->next;
delete q;
LinkPrint(L);
} while (L->next !=L);
cout << "最后一个出圈的编号是:" << num << endl;
return true;
}
int main()
{
LinkList* L, *s;
int i = 0;
//1、初始化一个空的循环链表
if (InitList(L))
{
cout << "成功初始化一个空的循环链表!" << endl;
}
else
{
exit(-1);
}
//尾插法
cout << "尾插法创建循环链表,插入10个元素。。。" << endl;
i = 0;
while ((++i) <= 10)
{
s = new LinkNode;
s->data = i;
s->next = NULL;
if (ListInsert_back(L, s))
{
cout << "插入成功!" << endl;
}
else
{
cout << "插入失败!" << endl;
}
}
cout << "尾插法创建循环链表输出结果为:\n";
LinkPrint(L);
//3、解答
Joseph(L,9);
system("pause");
return 0;
}
4、双向链表
#include<iostream>
#include<string>
using namespace std;
typedef struct _DoubleLinkNode
{
int data;
struct _DoubleLinkNode* next;
struct _DoubleLinkNode* prev;
}DbLinkNode, DbLinkList;
//构造一个空的双链表L
bool DbInit_List(DbLinkList* &L)
{
L = new DbLinkNode;
if (!L) return false;
L->next = NULL;
L->prev = NULL;
L->data = -1;
return true;
}
//前插法
bool DbListInsert_front(DbLinkList* &L, DbLinkList* node)
{
if (!L || !node) return false;
//1、只有头结点
if (L->next == NULL)
{
node->next = L->next;
node->prev = L; //新节点prev指针指向头结点
L->next = node; //头结点next指针指向新节点
}
else
{
L->next->prev = node; //第二个节点的prev指向新节点
node->next = L->next; //新节点的next指向新节点
node->prev = L; //新节点的prev指向头结点
L->next = node; //头结点的next节点指向新节点,完成插入
}
//也可以简写成
return true;
}
//尾插法
bool DbListInsert_back(DbLinkList*& L, DbLinkList* node)
{
DbLinkNode* last = NULL;
if (!L || !node) return false;
last = L;
while (last->next) last = last->next;
node->next = NULL;
last->next = node;
node->prev = last;
return true;
}
//任意位置插入元素
bool DbLink_Inset(DbLinkList* &L, int i, int& e) //这个i是第几个位置
{
if (!L || !L->next) return false;
if (i < 1) return false;
int j = 0;
DbLinkList* p, * s;
p = L;
while (p && j < i)
{
p = p->next;
j++;
}
if (!p || j != i)
{
cout << "不存在节点" <<i<< endl;
return false;
}
cout << "p: " << p << endl;
s = new DbLinkNode;
s->data = e;
s->next = p;
s->prev = p->prev;
p->prev->next = s;
p->prev = s;
return true;
}
//双向链表的遍历输出
void DbLink_Print(DbLinkList* &L)
{
DbLinkNode* p = NULL;
if (!L)
{
cout << "链表为空!" << endl;
return;
}
p = L;
cout << endl << "正向打印" << endl;
while (p->next)
{
cout << p->next->data << "\t";
p = p->next;
}
//逆向打印
cout << endl << "逆向打印" << endl;
while (p!=L)
{
cout << p->data << "\t";
p = p->prev;
}
cout << endl;
}
int main()
{
DbLinkList* L = NULL;
DbLinkNode* s = NULL;
//初始化一个空的双向链表
DbInit_List(L);
//使用前插法插入数据
int n;
cout << "前插法创建双向链表" << endl;
cout << "请输入元素个数:";
cin >> n;
cout << "\n请依次输入n的元素: " << endl;
while (n > 0)
{
s = new DbLinkNode;
cin >> s->data;
DbListInsert_front(L, s);
n--;
}
DbLink_Print(L);
//使用尾插法插入数据
cout << "尾插法创建链表!" << endl;
cout << "请输入元素个数:";
cin >> n;
cout << "\n请依次输入n的元素: " << endl;
while (n > 0)
{
s = new DbLinkNode;
cin >> s->data;
DbListInsert_back(L, s);
n--;
}
DbLink_Print(L);
//任意位置插入元素
for (int j = 0; j < 3; ++j)
{
int i, x;
cout << "请输入插入的位置和元素: ";
cin >> i;
cin >> x;
if (DbLink_Inset(L, i, x))
{
cout << "插入成功!" << endl;
}
else
{
cout << "插入失败!" << endl;
}
DbLink_Print(L);
}
system("pause");
return 0;
}
5、队列(顺序实现)
#include<iostream>
#include<string>
#include <iomanip>
using namespace std;
const int MaxSize = 5;
typedef int DataType;
typedef struct Queue
{
DataType queue[MaxSize];
int front; //队头指针
int rear; //队尾指针
}SeqQueue;
//队列的初始化
void InitQueue(SeqQueue* SQ)
{
if (!SQ) return;
SQ->front = SQ->rear = 0;
}
//判断队列是否满
int IsFull(SeqQueue* SQ)
{
if (!SQ) return 0;
if (SQ->rear == MaxSize)
{
return 1;
}
return 0;
}
//判断队列是否为空
int IsEmpty(SeqQueue *SQ)
{
if (!SQ) return 0;
if (SQ->front == SQ->rear)
{
return 1;
}
return 0;
}
//入队。将元素data插入到队列SQ中
int EnterQueue(SeqQueue* SQ, DataType data)
{
if (IsFull(SQ) == 1)
{
cout << "无法插入元素" << data << ",队列已满!" << endl;
return 0;
}
SQ->queue[SQ->rear] = data;
SQ->rear++;
return 1;
}
//出队,将队列中队头元素data出队,后面的元素向前移动
int DeleteQueue(SeqQueue* SQ, DataType *data)
{
if (!SQ || IsEmpty(SQ))
{
cout << "队列为空!" << endl;
return 0;
}
if (!data) return 0;
*data = SQ->queue[SQ->front];
for (int i = SQ->front + 1; i < SQ->rear; ++i)
{
SQ->queue[i - 1] = SQ->queue[i];
}
SQ->rear--;
return 1;
}
//出队2,将队头元素data出队,出队后队头指针front 后移一位
int DeleteQueue2(SeqQueue* SQ, DataType* data)
{
if (!SQ || IsEmpty(SQ))
{
cout << "队列为空!" << endl;
return 0;
}
if (SQ->front >= MaxSize)
{
cout << "出队已到尽头" << endl;
return 0;
}
*data = SQ->queue[SQ->front];
SQ->front = (SQ->front) + 1;
return 1;
}
//打印队列
void PrintQueue(SeqQueue* SQ)
{
if (!SQ) return;
int i = SQ->front;
while (i < SQ->rear)
{
cout << setw(4) << SQ->queue[i];
i++;
}
cout << endl;
}
//获取队首元素,不出队
int GetHead(SeqQueue* SQ, DataType *data)
{
if (!SQ || IsEmpty(SQ))
{
cout << "队列为空!" << endl;
}
if (data != NULL && SQ != NULL)
{
return *data = SQ->queue[SQ->front];
}
else
{
exit(-1);
}
}
//清空队列
void ClearQueue(SeqQueue* SQ)
{
if (!SQ) return;
SQ->front = SQ->rear = 0;
}
//获取队列中元素的个数
int GetLength(SeqQueue* SQ)
{
if (!SQ) return 0;
return SQ->rear - SQ->front;
}
int main()
{
SeqQueue* SQ = new SeqQueue;
DataType data;
//队列初始化
InitQueue(SQ);
//入队
for (int i = 0; i < 7; ++i)
{
EnterQueue(SQ, i);
}
cout << "队列中元素:";
PrintQueue(SQ);
cout << endl;
//获取队列中元素的个数
cout << "队列中元素的个数为:" << GetLength(SQ) << endl;
//出队1
if (DeleteQueue(SQ, &data))
{
cout << "出队1元素为: " << data << endl;
}
else
{
cout << "出队失败!" << endl;
}
cout << "队列中剩下的元素:";
PrintQueue(SQ);
cout << endl;
for (int i = 0; i < 10; ++i)
{
//出队2
if (DeleteQueue2(SQ, &data))
{
cout << "出队2元素为: " << data << endl;
}
else
{
cout << "出队失败!" << endl;
}
}
cout << "队列中剩下的元素:";
PrintQueue(SQ);
cout << endl;
system("pause");
return 0;
}
6、队列(链式队列)
#include<iostream>
#include<string>
#include <iomanip>
using namespace std;
const int MaxSize = 5;
typedef int DataType;
typedef struct _QNode
{
DataType data;
struct _QNode* next;
}QNode;
typedef QNode* QueuePtr;
typedef struct Queue
{
int length; //队列的长度
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
//队列初始化,将队列初始化为空队列
void InitQueue(LinkQueue* LQ)
{
if (!LQ) return;
LQ->length = 0;
LQ->front = LQ->rear = NULL; //把队头和队尾指针同时置0
}
//判断队列为空
int IsEmpty(LinkQueue* LQ)
{
if (!LQ) return 0;
if (LQ->front == NULL)
{
return 1;
}
return 0;
}
//判断队列是否为满
int IsFull(LinkQueue* LQ)
{
if (!LQ) return 0;
if (LQ->length == MaxSize)
{
return 1;
}
return 0;
}
//入队,将元素data 插入到队列LQ中
int EnterQueue(LinkQueue* LQ, DataType data)
{
if (!LQ) return 0;
if (IsFull(LQ))
{
cout << "无法插入元素:" << data << ",队列已满!" << endl;
return 0;
}
QNode* qNode = new QNode;
qNode->data = data;
qNode->next = NULL;
if (IsEmpty(LQ)) //空队列
{
LQ->front = LQ->rear = qNode;
}
else
{
LQ->rear->next = qNode; //在队尾插入节点 qNode
LQ->rear = qNode; //队尾指向新插入的节点
}
LQ->length++;
return 1;
}
//出队,将队列中队头元素data出队,后面的元素向前移动
int DeleteQueue(LinkQueue* LQ, DataType* data)
{
if (!LQ || IsEmpty(LQ))
{
cout << "队列为空!" << endl;
return 0;
}
QNode* tmp = NULL;
if (!data) return 0;
tmp = LQ->front;
LQ->front = tmp->next;
if (!LQ->front) LQ->rear = NULL;
*data = tmp->data;
LQ->length--;
delete tmp;
return 1;
}
//打印队列中的各元素
void PrintQueue(LinkQueue *LQ)
{
QNode* tmp;
if (!LQ) return;
if (LQ->front == NULL)
{
cout << "队列为空!" << endl;
return;
}
tmp = LQ->front;
while (tmp)
{
cout << setw(4) << tmp->data;
tmp = tmp->next;
}
cout << endl;
}
//获取队首元素
int GetHead(LinkQueue* LQ, DataType* data)
{
if (!LQ || IsEmpty(LQ))
{
cout << "队列为空!" << endl;
return 0;
}
if (!data) return 0;
*data = LQ->front->data;
return 1;
}
//清空队列
void ClearQueue(LinkQueue *LQ)
{
if (!LQ) return;
while (LQ->front)
{
QNode* tmp = LQ->front->next;
delete LQ->front;
LQ->front = tmp;
}
LQ->front = LQ->rear = NULL;
LQ->length = 0;
}
//获取队列中元素的个数
int getLength(LinkQueue* LQ)
{
if (!LQ || IsEmpty(LQ)) return 0;
return LQ->length;
}
int main()
{
LinkQueue* LQ = new LinkQueue;
DataType data = -1;
//初始化队列
InitQueue(LQ);
//入队
for (int i = 0; i < 7; ++i)
{
EnterQueue(LQ, i);
}
PrintQueue(LQ);
//出队
if (DeleteQueue(LQ, &data))
{
cout << "出队元素是:" << data << endl;
}
else
{
cout << "出队失败!" << endl;
}
//打印队列中的各元素
printf("出队一个元素后,队列中剩下的元素为 [%d]:", getLength(LQ));
PrintQueue(LQ);
cout << endl;
ClearQueue(LQ);
cout << "清空队列!" << endl;
PrintQueue(LQ);
delete LQ;
system("pause");
return 0;
}
7、任务队列(应用)
#include <stdio.h>
#include <assert.h>
#include <Windows.h>
#include <iostream>
#include <iomanip>
using namespace std;
const int MaxSize = 1000; //队列最大容量
typedef struct _QNode
{
int id;
void (*handler)(void);
struct _QNode* next;
}QNode;
typedef QNode* QueuePtr;
typedef struct Queue
{
int length; //队列的长度
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
//分配线程执行的任务节点
QueuePtr thread_task_alloc()
{
QNode* task;
task = (QNode*)calloc(1, sizeof(QNode));
if (task == NULL)
{
return NULL;
}
return task;
}
//队列初始化,将队列初始化为空队列
void InitQueue(LinkQueue* LQ)
{
if (!LQ) return;
LQ->length = 0;
LQ->front = LQ->rear = NULL; //把对头和队尾指针同时置 0
}
//判断队列为空
int IsEmpty(LinkQueue * LQ)
{
if (!LQ) return 0;
if (LQ->front == NULL)
{
return 1;
}
return 0;
}
//判断队列是否为满
int IsFull(LinkQueue* LQ)
{
if (!LQ) return 0;
if (LQ->length == MaxSize)
{
return 1;
}
return 0;
}
//入队,将元素 data 插入到队列 LQ 中
int EnterQueue(LinkQueue* LQ, QNode* node)
{
if (!LQ || !node) return 0;
if (IsFull(LQ)) {
cout << "无法插入任务 " << node->id << ", 队列已满!" << endl;
return 0;
}
node->next = NULL;
if (IsEmpty(LQ)) {//空队列
LQ->front = LQ->rear = node;
}
else {
LQ->rear->next = node;//在队尾插入节点 qNode
LQ->rear = node; //队尾指向新插入的节点
}
LQ->length++;
return 1;
}
//出队,将队列中队头的节点出队,返回头节点
QNode* PopQueue(LinkQueue* LQ)
{
QNode* tmp = NULL;
if (!LQ || IsEmpty(LQ)) {
cout << "队列为空!" << endl;
return 0;
}
tmp = LQ->front;
LQ->front = tmp->next;
if (!LQ->front) LQ->rear = NULL;//如果对头出列后不存在其他元素,则rear 节点也要置空
LQ->length--;
return tmp;
}
//打印队列中的各元素
void PrintQueue(LinkQueue* LQ)
{
QueuePtr tmp;
if (!LQ) return;
if (LQ->front == NULL) {
cout << "队列为空!";
return;
}
tmp = LQ->front;
while (tmp)
{
cout << setw(4) << tmp->id;
tmp = tmp->next;
}
cout << endl;
}
//获取队列中元素的个数
int getLength(LinkQueue* LQ)
{
if (!LQ) return 0;
return LQ->length;
}
void task1()
{
printf("我是任务1....\n");
}
void task2()
{
printf("我是任务2....\n");
}
int main()
{
LinkQueue* LQ = new LinkQueue;
QNode* task = NULL;
//初始化队列
InitQueue(LQ);
//任务1入队
task = thread_task_alloc();
task->id = 1;
task->handler= &task1;
EnterQueue(LQ,task);
//任务2入队
task = thread_task_alloc();
task->id = 2;
task->handler = &task2; //将函数的地址赋给handler
EnterQueue(LQ, task);
//打印任务队列中的元素
printf("队列中的元素(总共%d 个):", getLength(LQ));
PrintQueue(LQ);
cout << endl;
//执行任务
while ((task =PopQueue(LQ)))
{
task->handler(); //调用函数
delete task;
}
//清理资源
delete LQ;
system("pause");
return 0;
}
8、循环队列
#include<iostream>
#include<string>
#include <iomanip>
using namespace std;
const int MaxSize = 5;
typedef int DataType;
typedef struct Queue
{
DataType queue[MaxSize];
int front;
int rear;
}SeqQueue;
//队列初始化,将循环队列初始化为空队列
void InitQueue(SeqQueue* SQ)
{
if (!SQ) return;
SQ->front = SQ->rear = 0; //把对头和队尾指针同时置 0
}
//判断队列为空
int IsEmpty(SeqQueue* SQ)
{
if (!SQ) return 0;
if (SQ->front=SQ->rear)
{
return 1;
}
return 0;
}
//判断循环队列是否为满
int IsFull(SeqQueue* SQ)
{
if (!SQ) return 0;
if ((SQ->rear + 1) % MaxSize == SQ->front)
{
return 1;
}
return 0;
}
//入队,将元素 data 插入到循环队列 SQ 中
int EnterQueue(SeqQueue* SQ, DataType data)
{
if (!SQ) return 0;
if (IsFull(SQ))
{
cout << "无法插入元素 " << data << ", 队列已满!" << endl;
return 0;
}
SQ->queue[SQ->rear] = data; //在队尾插入元素 data
SQ->rear = (SQ->rear + 1) % MaxSize; //队尾指针循环后移一位
return 1;
}
//出队,将队列中队头的元素 data 出队,出队后队头指针 front 后移一位
int DeleteQueue(SeqQueue* SQ, DataType* data)
{
if (!SQ || IsEmpty(SQ))
{
cout << "循环队列为空!" << endl;
return 0;
}
*data = SQ->queue[SQ->front]; //出队元素值
SQ->front = (SQ->front + 1) % MaxSize; //队首指针后移一位
return 1;
}
//打印队列中的各元素
void PrintQueue(SeqQueue* SQ)
{
if (!SQ) return;
int i = SQ->front;
while (i != SQ->rear)
{
cout << setw(4) << SQ->queue[i];
i = (i + 1) % MaxSize;
}
cout << endl;
}
//获取队首元素,不出队
int GetHead(SeqQueue* SQ, DataType* data)
{
if (!SQ || IsEmpty(SQ))
{
cout << "队列为空!" << endl;
}
if (SQ!=NULL && data!=NULL)
{
return *data = SQ->queue[SQ->front];
}
else
{
return -1;
}
}
//清空队列
void ClearQueue(SeqQueue* SQ)
{
if (!SQ) return;
SQ->front = SQ->rear = 0;
}
//获取队列中元素的个数
int getLength(SeqQueue* SQ) {
if (!SQ) return 0;
return (SQ->rear - SQ->front + MaxSize) % MaxSize;
}
int main()
{
SeqQueue* SQ = new SeqQueue;
DataType data = -1;
//初始化队列
InitQueue(SQ);
//入队
for (int i = 0; i < 7; i++)
{
EnterQueue(SQ, i);
}
//打印队列中的元素
printf("队列中的元素(总共%d 个):", getLength(SQ));
PrintQueue(SQ);
cout << endl;
//出队
for (int i = 0; i < 5; i++)
{
if (DeleteQueue(SQ, &data)) {
cout << "出队的元素是:" << data << endl;
}
else {
cout << "出队失败!" << endl;
}
}
//打印队列中的元素
printf("出队五个元素后,队列中剩下的元素个数为 %d 个:",
getLength(SQ));
PrintQueue(SQ);
cout << endl;
//入队 4 个
for (int i = 0; i < 4; i++)
{
EnterQueue(SQ, i + 10);
}
printf("\n 入队四个元素后,队列中剩下的元素个数为 %d 个:",
getLength(SQ));
PrintQueue(SQ);
system("pause");
return 0;
}
9、堆的算法(建最大堆、插入新元素)
#include<iostream>
#include<string>
using namespace std;
const int DEFAULT_CAPCITY = 128;
typedef struct _Heap
{
int *arr; //存储堆元素的数组
int size; //当前已存储元素的个数
int capacity; //当前存储的容量
}Heap;
bool initHeap(Heap& heap, int* orginal, int size);
bool insert(Heap& heap, int value);
static void buildHeap(Heap& heap);
static void adjustDown(Heap& heap, int index);
static void adjustUp(Heap& heap, int index);
//初始化堆
bool initHeap(Heap& heap, int* orginal, int size)
{
int capacity = DEFAULT_CAPCITY > size ? DEFAULT_CAPCITY : size;
heap.arr = new int[capacity];
if (!heap.arr) return false;
heap.capacity = capacity;
heap.size = 0;
//如果存在原始数据则构建堆
if (size > 0)
{
//方法一:直接调整所有元素
//memcpy(heap.arr, orginal, size * sizeof(int));
//heap.size = size;
建堆
//buildHeap(heap);
//方法二:一次插入一个
for (int i = 0; i < size; ++i)
{
insert(heap, orginal[i]);
}
}
return true;
}
//建堆
void buildHeap(Heap& heap)
{
for (int i = heap.size / 2 - 1; i >= 0; i--)
{
adjustDown(heap, i);
}
}
//从上向下
void adjustDown(Heap& heap, int index)
{
int cur = heap.arr[index];
int parent,child;
for (parent = index; (parent * 2 + 1) < heap.size;parent=child)
{
child = parent * 2 + 1;
if (child + 1 < heap.size && heap.arr[child] < heap.arr[child + 1])
{
child++;
}
if (cur > heap.arr[child])
{
break;
}
else
{
heap.arr[parent] = heap.arr[child];
heap.arr[child] = cur;
}
}
}
//最大堆尾部插入节点,同时保证最大堆的特性
bool insert(Heap& heap, int value)
{
if (heap.size == heap.capacity)
{
fprintf(stderr, "栈空间耗尽!\n");
return false;
}
int index = heap.size;
heap.arr[heap.size++] = value;
adjustUp(heap, index);
return true;
}
/*将当前的节点和父节点调整成最大堆*/
void adjustUp(Heap& heap, int index)
{
if (index<0 || index>heap.size)
{
return;
}
while (index > 0)
{
int temp = heap.arr[index];
int parent = (index - 1) / 2;
if (parent >= 0) //如果索引没有出界就执行想要的操作
{
if (temp > heap.arr[parent])
{
heap.arr[index] = heap.arr[parent];
heap.arr[parent] = temp;
index = parent;
}
else //如果已经比父亲小 直接结束循环
{
break;
}
}
else //越界结束循环
{
break;
}
}
}
int main()
{
Heap hp;
int origVals[] = { 1,2,3,87,93,82,92,86,95 };
int i = 0;
if (!initHeap(hp, origVals, sizeof(origVals) / sizeof(origVals[0])))
{
fprintf(stderr, "初始化堆失败! \n");
exit(-1);
}
for (i = 0; i < hp.size; i++)
{
printf("the %dth element:%d\n", i, hp.arr[i]);
}
insert(hp, 99);
printf("在堆中插入新的元素 99,插入结果:\n");
for (i = 0; i < hp.size; i++)
{
printf("the %dth element:%d\n", i, hp.arr[i]);
}
system("pause");
return 0;
}
10、堆排
#include<iostream>
#include<string>
using namespace std;
typedef struct _Heap
{
int* arr; //存储堆元素的数组
int size; //当前已存储元素的个数
int capacity; //当前存储的容量
}Heap;
bool initHeap(Heap& heap, int* orginal, int size);
bool popMax(Heap& heap, int& value);
void heapSort(Heap& heap);
static void buildHeap(Heap& heap);
static void adjustDown(Heap& heap, int index);
//初始化堆
bool initHeap(Heap& heap, int* orginal, int size)
{
heap.arr = orginal;
if (!heap.arr) return false;
heap.capacity = size;
heap.size = size;
//如果存在原始数据则构建堆
if (size > 0)
{
//方法一:直接调整所有元素
//建堆
buildHeap(heap);
}
return true;
}
//建堆
void buildHeap(Heap& heap)
{
for (int i = heap.size / 2 - 1; i >= 0; i--)
{
adjustDown(heap, i);
}
}
//从上向下
void adjustDown(Heap& heap, int index)
{
int cur = heap.arr[index];
int parent, child;
for (parent = index; (parent * 2 + 1) < heap.size; parent = child)
{
child = parent * 2 + 1;
if (child + 1 < heap.size && heap.arr[child] < heap.arr[child + 1])
{
child++;
}
if (cur > heap.arr[child])
{
break;
}
else
{
heap.arr[parent] = heap.arr[child];
heap.arr[child] = cur;
}
}
}
//实现堆排序
void heapSort(Heap &heap)
{
if (heap.size < 1) return;
while (heap.size > 0)
{
int tmp = heap.arr[0];
heap.arr[0] = heap.arr[heap.size - 1];
heap.arr[heap.size - 1] = tmp;
heap.size--;
adjustDown(heap, 0);
}
}
//删除最大的节点,并获得节点的值*
bool PopMax(Heap &heap, int& value)
{
if (heap.size < 1) return false;
value = heap.arr[0];
heap.arr[0] = heap.arr[heap.size--];
adjustDown(heap, 0);
return true;
}
int main()
{
Heap hp;
int origVals[] = { 1,2,3,87,93,82,92,86,95 };
int i = 0;
if (!initHeap(hp, origVals, sizeof(origVals) / sizeof(origVals[0])))
{
fprintf(stderr, "初始化堆失败! \n");
exit(-1);
}
for (i = 0; i < hp.size; i++)
{
printf("the %dth element:%d\n", i, hp.arr[i]);
}
//执行堆排序
heapSort(hp);
cout << "堆排序后的结果:\n" << endl;
for (int i = 0; i < sizeof(origVals) / sizeof(origVals[0]); ++i)
{
printf(" %d",origVals[i]);
}
system("pause");
return 0;
}
11、栈的算法实现
#include <Windows.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
const int MaxSize = 128;
typedef int ElemType;
typedef struct _SqStack
{
ElemType* base; //栈底指针
ElemType* top; //栈顶指针
}SqStack;
//构造一个空栈 S
bool InitStack(SqStack& S)
{
S.base = new ElemType[MaxSize];
if (!S.base) return false;
S.top = S.base;
return true;
}
// 插入元素 e 为新的栈顶元素
bool PushStack(SqStack& S, ElemType e)
{
if (S.top - S.base == MaxSize) return false;
*(S.top++)= e;
return true;
}
//删除 S 的栈顶元素,暂存在变量 e
bool PopStack(SqStack& S, ElemType& e)
{
if (S.base == S.top) return false;
e = *(--S.top);
return true;
}
//返回 S 的栈顶元素,栈顶指针不变
//ElemType GetTop(SqStack& S) //返回 S 的栈顶元素,栈顶指针不变
//{
// if (S.top != S.base)
// { //栈非空
// return *(S.top - 1); //返回栈顶元素的值,栈顶指针不变
// }
// else {
// return -1;
// }
//}
//返回栈顶元素
bool GetTop1(SqStack& S, ElemType& e)
{
if (S.top != S.base)
{
e = *(S.top - 1);
}
else
{
return false;
}
}
//返回栈中元素个数
int GetSize(SqStack& S)
{
return (S.top-S.base);
}
//判断栈是否为空
bool IsEmpty(SqStack& S)
{
if (S.top == S.base)
{
return true;
}
else
{
return false;
}
}
//销毁栈
void DestoryStack(SqStack& S)
{
if (S.base)
{
delete(S.base);
S.base = NULL;
S.top = NULL;
}
}
int main()
{
int n, x;
SqStack S;
InitStack(S);
cout << "请输入元素个数 n:" << endl;
cin >> n;
cout << "请依次输入 n 个元素,依次入栈:" << endl;
while (n--)
{
cin >> x;
PushStack(S, x);
}
cout << "元素依次出栈:" << endl;
ElemType topElement;
while (GetTop1(S, topElement))
{
cout << topElement << "\t";
PopStack(S, x);
}
cout << endl;
DestoryStack(S);
system("pause");
return 0;
}
12、栈的应用(回溯法)
**maze.h**
#pragma once
#include<stdio.h>
#include<stdlib.h>
const int MAXSIZE = 100;
typedef struct _Position
{
int _x;
int _y;
}Position;
const int MaxSize = 128;
typedef Position ElemType;
typedef struct _SqStack
{
ElemType* base; //栈底指针
ElemType* top; //栈顶指针
}SqStack;
bool InitStack(SqStack& S)
{
S.base = new ElemType[MaxSize];
if (!S.base) return false;
S.top = S.base;
return true;
}
//插入新元素
bool PushStack(SqStack &S, ElemType e)
{
if (S.top - S.base == MaxSize) //栈满
return false;
*(S.top++) = e; //元素 e 压入栈顶,然后栈顶指针加 1,等价于*S.top=e;
S.top++;
return true;
}
bool PopStack(SqStack& S, ElemType& e) //删除 S 的栈顶元素,暂存在变量 e中
{
if (S.base == S.top) //栈空
{
return false;
}
e = *(--S.top); //栈顶指针减 1,将栈顶元素赋给 e
return true;
}
ElemType* GetTop(SqStack& S) //返回 S 的栈顶元素,栈顶指针不变
{
if (S.top != S.base) //栈非空
{
return S.top - 1; //返回栈顶元素的值,栈顶指针不变
}
else {
return NULL;
}
}
int GetSize(SqStack& S) //返回栈中元素个数
{
return (S.top - S.base);
}
bool IsEmpty(SqStack& S) //判断栈是否为空
{
if (S.top == S.base)
{
return true;
}
else {
return false;
}
}
void DestoryStack(SqStack& S) //销毁栈
{
if (S.base)
{
delete (S.base);
S.base = NULL;
S.top = NULL;
}
}
**maze.cpp**
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "maze.h"
#include <assert.h>
#include <iostream>
const int ROW = 6;
const int COL = 6;
typedef struct _Maze
{
int map[ROW][COL];
}Maze;
//迷宫的初始化
void InitMaze(Maze* m, int map[ROW][COL])
{
for (int i = 0; i < ROW; ++i)
{
for (int j = 0; j < COL; ++j)
{
m->map[i][j] = map[i][j];
}
}
}
//打印迷宫
void PrintMaze(Maze* m)
{
for (int i = 0; i < ROW; ++i)
{
for (int j = 0; j < COL; ++j)
{
printf("%d ", m->map[i][j]);
}
printf("\n");
}
printf("\n");
}
//判断是否是有效入口
int IsValidEnter(Maze* m, Position cur)
{
assert(m);
if ( (cur._x == 0 || cur._x == ROW - 1) || (cur._y == 0 || cur._y == COL - 1) && (m->map[cur._x][cur._y] == 1))
{
return 1;
}
else
{
return 0;
}
}
//判断当前节点的下一个节点能否走通
int IsNextPass(Maze* m, Position cur, Position next)
{
assert(m);
//判断 next 节点是否为 cur 的下一节点
if ((next._x == cur._x && ((next._y == cur._y + 1) || (next._y ==cur._y - 1))) || (next._y == cur._y && ((next._x == cur._x + 1) || (next._x == cur._x - 1))))
{
if ((next._x >= 0 && next._x < ROW) && (next._y >= 0 && next._y < COL) && (m->map[next._x][next._y] == 1))
{
return 1;
}
}
return 0;
}
//判断当前节点是不是有效的迷宫出口
int IsValidExit(Maze* m, Position cur, Position enter)
{
assert(m);
//这里首先得保证该节点不是入口点,其次只要它处在迷宫的边界即可
if ((cur._x != enter._x || cur._y != enter._y) && ((cur._x == 0 || cur._x == ROW - 1) || (cur._y == 0 || cur._y == COL - 1)))
{
return 1;
}
else
{
return 0;
}
}
//找迷宫通路
int PassMaze(Maze* m, Position enter, SqStack* s)
{
assert(m && IsValidEnter(m, enter) == 1);
Position cur = enter;
Position next;
PushStack(*s, cur);
m->map[cur._x][cur._y] = 2;
while (!IsEmpty(*s))
{
cur = *GetTop(*s);
if (IsValidExit(m, cur, enter) == 1) return 1;
//向左一步
next = cur;
next._y = cur._y - 1;
if (IsNextPass(m, cur, next) == 1)
{
PushStack(*s, next);
m->map[next._x][next._y] = m->map[cur._x][cur._y] + 1;
continue;
}
//向上一步
next = cur;
next._x = cur._x - 1;
if (IsNextPass(m, cur, next) == 1)
{
PushStack(*s, next);
m->map[next._x][next._y] = m->map[cur._x][cur._y] + 1;
continue;
}
//向右一步
next = cur;
next._y = cur._y +1;
if (IsNextPass(m, cur, next) == 1)
{
PushStack(*s, next);
m->map[next._x][next._y] = m->map[cur._x][cur._y] + 1;
continue;
}
//向下一步
next = cur;
next._x = cur._x +1;
if (IsNextPass(m, cur, next) == 1)
{
PushStack(*s, next);
m->map[next._x][next._y] = m->map[cur._x][cur._y] + 1;
continue;
}
Position tmp;
PopStack(*s, tmp);
}
return 0;
}
int main()
{
int map[ROW][COL] = //用二维数组描绘迷宫:1 代表通路,0 代表墙
{
0,0,1,0,0,0,
0,0,1,1,1,0,
0,0,1,0,0,0,
0,1,1,1,1,0,
0,0,1,0,1,0,
0,0,0,0,1,0
};
Maze m;
Position enter;
enter._x = 0;
enter._y = 2;
InitMaze(&m, map);
PrintMaze(&m);
SqStack s;
InitStack(s);
int ret = PassMaze(&m, enter, &s);
if (ret)
{
std::cout << "找到出口!" << std::endl;
}
else
{
std::cout << "没出口!" << std::endl;
}
PrintMaze(&m);
system("pause");
return 0;
}
13、二叉树算法实现
#include<stdio.h>
#include<stdlib.h>
#include <cassert>
#include <iostream>
#include "maze.h"
using namespace std;
#define MAX_NODE 1024
#define isLess(a,b) (a<b)
#define isEqual(a,b) (a==b)
typedef int ElemType;
typedef struct _Bnode
{
ElemType data;
struct _Bnode* lchild, * rchild;
}Bnode,Btree;
//二叉搜索树插入节点
bool InsertBtree(Btree** root, Bnode* node) {
Bnode* tmp = NULL;
Bnode* parent = NULL;
if (!node)
{
return false;
}
else {//清空新节点的左右子树
node->lchild = NULL;
node->rchild = NULL;
}
if (*root) {//存在根节点
tmp = *root;
}
else { //不存在根节点
*root = node;
return true;
}
while (tmp != NULL) {
parent = tmp;//保存父节点
//printf("父节点: %d\n", parent->data);
if (isLess(node->data, tmp->data)) {
tmp = tmp->lchild;
}
else {
tmp = tmp->rchild;
}
}
//若该树为空树,则直接将 node 放置在根节点上
if (isLess(node->data, parent->data)) {//找到空位置后,进行插入
parent->lchild = node;
}
else {
parent->rchild = node;
}
return true;
}
//回调函数查找左子树的最大值
int findMax(Btree* root)
{
//一、递归
if (root->rchild == NULL)
{
return root->data;
}
return findMax(root->rchild);
//二、循环
/*while (root->rchild)
{
root = root->rchild;
}
return root->data;*/
}
//删除节点
Btree* DeleteNode(Btree* root, int key,Bnode* &deleteNode)
{
if (root == NULL)return NULL;//没有找到删除节点
if (root->data > key)
{
root->lchild = DeleteNode(root->lchild, key, deleteNode);
return root;
}
if (root->data < key)
{
root->rchild = DeleteNode(root->rchild, key, deleteNode);
return root;
}
deleteNode = root;
//删除节点不存在左右子节点,即为叶子节点,直接删除
if (root->lchild == NULL && root->rchild == NULL) return NULL;
//删除节点只存在右子节点,直接用右子节点取代删除节点
if (root->lchild == NULL && root->rchild != NULL) return root->rchild;
//删除节点只存在左子节点,直接用左子节点取代删除节点
if (root->lchild != NULL && root->rchild == NULL) return root->lchild;
//删除节点存在左右子节点,直接用左子节点最大值取代删除节点
int val = findMax(root->lchild);
root->data = val;
root->lchild = DeleteNode(root->lchild, val, deleteNode);
return root;
}
//查找节点********递归调用*********
Bnode* QueryByRec(Btree* root, ElemType e)
{
if (root == NULL) {
return NULL; // 如果树为空,直接返回 NULL
}
if (isEqual(root->data, e))
{
return root;
}
else if (isLess(e, root->data))
{
return QueryByRec(root->lchild, e);
}
else
{
return QueryByRec(root->rchild, e);
}
}
//查找节点*******非递归调用*********
Bnode* QueryLoop(Btree* root, int e)
{
while (!isEqual(root->data, e) && root != NULL)
{
if (isLess(e, root->data))
{
root = root->lchild;
}
else
{
root = root->rchild;
}
}
return root;
}
//前序遍历
void PreOrderRec(Btree* root)
{
if (root == NULL)
{
return ;
}
printf("-%d-", root->data);
PreOrderRec(root->lchild);
PreOrderRec(root->rchild);
}
//中序遍历
void InOrderRec(Btree* root)
{
if (root == NULL)
{
return;
}
InOrderRec(root->lchild);
printf("-%d-", root->data);
InOrderRec(root->rchild);
}
//后序遍历
void PostOrderRec(Btree* root)
{
if (root == NULL)
{
return;
}
PostOrderRec(root->lchild);
PostOrderRec(root->rchild);
printf("-%d-", root->data);
}
/***************
借助队列实现前序遍历
*************/
// 前序遍历非递归 /**************代码有点问题************************/
//void PreOrderRec1(Btree* root) {
// if (root == NULL) {
// return;
// }
//
// SqStack stack;
// InitStack(stack);
// Btree* currentNode = root;
//
// while (currentNode != NULL || stack.top != 0)
// {
// while (currentNode != NULL)
// {
// cout << currentNode->data << " "; // 访问节点
// PushStack(stack, reinterpret_cast<ElemType>(currentNode));
// currentNode = currentNode->lchild;
// }
//
// if (stack.top != 0)
// {
// PopStack(stack, reinterpret_cast<ElemType&>(currentNode));
// currentNode = currentNode->rchild;
// }
// }
//}
int main()
{
int test[] = { 19, 7, 25, 5, 11, 15, 21, 61 };
Bnode* root = NULL, * node = NULL;
node = new Bnode;
node->data = test[0];
InsertBtree(&root, node);
for (int i = 1; i < sizeof(test) / sizeof(test[0]); ++i)
{
node = new Bnode;
node->data = test[i];
if (InsertBtree(&root, node))
{
printf("节点 %d 插入成功\n ", node->data);
}
}
std::cout << "前序遍历:" << std::endl;
PreOrderRec(root);
//二叉搜索树删除
Bnode* deleteNode = NULL;
DeleteNode(root, 15, deleteNode);
printf("二叉搜索树删除节点 15, %s\n", deleteNode ? "存在,删除成功" : "节点不存在,删除失败");
if (deleteNode) delete deleteNode;
//前中后遍历
std::cout << "前序遍历:" << std::endl;
PreOrderRec(root);
std::cout << "中序遍历:" << std::endl;
InOrderRec(root);
std::cout << "后序遍历:" << std::endl;
PostOrderRec(root);
//二叉搜索树查找节点
Bnode *node1=QueryByRec(root, 20);
printf("搜索二叉树,节点20 %s\n", node1 ? "存在":"不存在");
Bnode* node2 = QueryLoop(root, 21);
printf("搜索二叉树,节点21%s\n", node2 ? "存在" : "不存在");
system("pause");
return 0;
}
13、图的深读遍历
#include<iostream>
#include<string>
#include<queue>
using namespace std;
const int MaxSize = 1024;
bool visited[MaxSize];
typedef struct _EdgeNode {//与节点连接的边的定义
int adjvex; //邻接的顶点
int weight; //权重
struct _EdgeNode *next; //下一条边
}EdgeNode;
typedef struct _VertexNode {//顶点节点
char data; //节点数据
struct _EdgeNode* first;//指向邻接第一条边
}VertexNode, AdjList;
typedef struct _AdjListGraph {
AdjList* adjlist;
int vex; //顶点数
int edge; //边数
}AdjListGraph;
//图的初始化
void Init(AdjListGraph& G)
{
G.adjlist = new AdjList[MaxSize];
G.edge = 0;
G.vex = 0;
for (int i = 0; i < MaxSize; ++i)
{
visited[i] = false;
}
}
//通过顶点对应的字符寻找顶点在图中的邻接点
int Location(AdjListGraph & G, char c)
{
for (int i = 0; i < G.vex; i++)
{
if (G.adjlist[i].data == c)
{
return i;
}
}
return -1;
}
//图的创建
void Greate(AdjListGraph& G)
{
cout << "请输入该图的顶点数以及边数:" << endl;
cin >> G.vex >> G.edge;
cout << "请输入相关顶点:" << endl;
for (int i = 0; i < G.vex; ++i)
{
cin >> G.adjlist[i].data;
G.adjlist[i].first = NULL;
}
char v1 = 0, v2 = 0;
int i1, i2;
cout << "请输入想关联边的顶点:" << endl;
for (int i = 0; i < G.edge; ++i)
{
cin >> v1 >> v2;
i1 = Location(G, v1);
i2 = Location(G, v2);
if (i1 != -1 && i2!= -1)
{
EdgeNode* temp = new EdgeNode;
temp->adjvex = i2;
temp->next = G.adjlist[i1].first;
G.adjlist[i1].first = temp;
}
}
}
//对图上的顶点进行深度遍历
void DFS(AdjListGraph& G,int v)
{
int next = -1;
if (visited[v]) return;
cout << G.adjlist[v].data << " ";
visited[v]= true;
EdgeNode* temp = G.adjlist[v].first;
while (temp)
{
next = temp->adjvex;
temp = temp->next;
if (visited[next] == false)
{
DFS(G, next);
}
}
}
//对所有顶点进行深度遍历
void DFS_Main(AdjListGraph& G)
{
for (int i = 0; i < G.vex; ++i)
{
if (visited[i] == false)
{
DFS(G, i);
}
}
}
int main()
{
AdjListGraph G;
Init(G);
Greate(G);
DFS_Main(G);
system("pause");
return 0;
}
14、图的广度遍历
#include<iostream>
#include<string>
#include<queue>
using namespace std;
const int MaxSize = 1024;
bool visited[MaxSize];
typedef struct _EdgeNode {//与节点连接的边的定义
int adjvex; //邻接的顶点
int weight; //权重
struct _EdgeNode* next; //下一条边
}EdgeNode;
typedef struct _VertexNode {//顶点节点
char data; //节点数据
struct _EdgeNode* first;//指向邻接第一条边
}VertexNode, AdjList;
typedef struct _AdjListGraph {
AdjList* adjlist;
int vex; //顶点数
int edge; //边数
}AdjListGraph;
//图的初始化
void Init(AdjListGraph& G)
{
G.adjlist = new AdjList[MaxSize];
G.edge = 0;
G.vex = 0;
for (int i = 0; i < MaxSize; ++i)
{
visited[i] = false;
}
}
//通过顶点对应的字符寻找顶点在图中的邻接点
int Location(AdjListGraph& G, char c)
{
for (int i = 0; i < G.vex; i++)
{
if (G.adjlist[i].data == c)
{
return i;
}
}
return -1;
}
//图的创建
void Greate(AdjListGraph& G)
{
cout << "请输入该图的顶点数以及边数:" << endl;
cin >> G.vex >> G.edge;
cout << "请输入相关顶点:" << endl;
for (int i = 0; i < G.vex; ++i)
{
cin >> G.adjlist[i].data;
G.adjlist[i].first = NULL;
}
char v1 = 0, v2 = 0;
int i1, i2;
cout << "请输入想关联边的顶点:" << endl;
for (int i = 0; i < G.edge; ++i)
{
cin >> v1 >> v2;
i1 = Location(G, v1);
i2 = Location(G, v2);
if (i1 != -1 && i2 != -1)
{
EdgeNode* temp = new EdgeNode;
temp->adjvex = i2;
temp->next = G.adjlist[i1].first;
G.adjlist[i1].first = temp;
}
}
}
//对图上的顶点进行广度遍历
void BFS(AdjListGraph& G, int v)
{
queue<int> q;
q.push(v);
int cur = -1;
int index;
while (!q.empty())
{
cur = q.front();
if (visited[cur] == false)
{
cout << G.adjlist[cur].data << " ";
visited[cur] = true;
}
q.pop();
EdgeNode* temp = G.adjlist[cur].first;
while (temp)
{
index = temp->adjvex;
temp = temp->next;
q.push(index);
}
}
}
//对所有顶点进行广度遍历
void BFS_Main(AdjListGraph& G)
{
for (int i = 0; i < G.vex; ++i)
{
if (visited[i] == false)
{
BFS(G, i);
}
}
}
int main()
{
AdjListGraph G;
Init(G);
Greate(G);
BFS_Main(G);
system("pause");
return 0;
}
五大核心算法:
1、分治法——二分查找
#include <stdio.h>
#include <stdlib.h>,
#include <iostream>
using namespace std;
int BinarySearch(int* arr, int minSub, int maxSub, int num)
{
if (minSub > maxSub)
{
return -1;
}
int mid = (minSub + maxSub) / 2;
if (num == arr[mid])
{
return mid;
}
else if (num <arr[mid])
{
return BinarySearch(arr, minSub, mid-1, num);
}
else
{
return BinarySearch(arr, mid+1,maxSub, num);
}
return -1;
}
int main()
{
int girls[] = { 5,7,11,15,19,21,25,26,61,99 };
int index = BinarySearch(girls, 0, 9, 26);
if (index!=- 1)
{
cout << "找到了 " << 26 << "索引为:" << index << endl;
}
else
{
cout << "没找到!" << endl;
}
system("pause");
return 0;
}
2、动态规划:
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;
//法一:
int WalkCount(int n)
{
if (n <= 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
else
{
return WalkCount(n - 1) + WalkCount(n - 2);
}
}
//法二:动态规划
int WalkCount2(int n)
{
int ret = 0;
if (n <= 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
int *values= new int[n + 1];
values[0] = 0;
values[1] = 1;
values[2] = 2;
for (int i = 3; i <= n; ++i)
{
values[i] = values[i - 1] + values[i - 2];
}
ret= values[n];
delete [] values;
return ret;
}
int main()
{
int n = 0;
cout << "请输入台阶的阶数:" << endl;
scanf_s("%d", &n);
for (int i = 0; i <= n;++i)
{
printf("走 %d 级台阶共有: %d 种走法\n", i, WalkCount2(i));
}
system("pause");
return 0;
}
3、回溯法:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool dfs(vector<vector<char>>& matrix, const string& str, vector<vector<bool>> visited, int row, int col, int k);
bool hasPath(vector<vector<char>>& matrix, const string& str)
{
if (matrix.empty() || str.empty())
{
return false;
}
int rows = matrix.size();
int cols = matrix[0].size();
vector<vector<bool>> visited(rows, vector<bool>(cols, false));
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
if (dfs(matrix, str, visited, i, j, 0))
{
return true;
}
}
}
return false;
}
bool dfs(vector<vector<char>>& matrix, const string& str, vector<vector<bool>> visited, int row, int col, int k)
{
if (row < 0 || row >= matrix.size() || col < 0 || col>=matrix[0].size() || matrix[row][col] != str[k])
{
return false;
}
if (k == str.size() - 1)
{
return true;
}
visited[row][col] = true;
bool found =
dfs(matrix, str, visited, row + 1, col, k + 1) ||
dfs(matrix, str, visited, row - 1, col, k + 1) ||
dfs(matrix, str, visited, row, col + 1, k + 1) ||
dfs(matrix, str, visited, row, col - 1, k + 1);
if (!found)
{
visited[row][col] = false;
}
return found;
}
int main()
{
vector<vector<char>> matrix =
{
{'A', 'B', 'T', 'G'},
{'C', 'F', 'C', 'S'},
{'J', 'D', 'E', 'H'}
};
string str = "ABFD";
if (hasPath(matrix,str))
{
cout << "存在" << endl;
}
else
{
cout << "不存在" << endl;
}
}
4、贪婪算法:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
const int N = 7;
int value[N] = { 1,2,5,10,20,50,100 };
int count[N] = { 10,2,3,1,2,3,5 };
int slove(int money)
{
int num = 0;
int i = 0;
for (int i = N - 1; i >= 0; --i)
{
int count[N] = { 10,2,3,1,2,3,5 };
int j = money / value[i];
int c = j > count[i] ? count[i] : j;
printf("需要的面值%d 的纸币 %d 张\n", value[i], c);
money = money - c * value[i];
num = num + c;
if (money == 0) break;
}
if (money > 0) num = -1;
return num;
}
int main()
{
int money = 0;
int num= 0;
printf("请输入要支付的零钱的数目:\n");
//scanf_s("%s", &money);
cin >> money;
num = slove(money);
if (num == -1)
{
printf("对不起,找不开\n");
}
else
{
printf("成功的使用至少%d 张纸币实现找零/支付!\n", num);
}
system("pause");
return 0;
}
5、分支边界法
代码略
七大排序:
1、选择排序:
#include <stdio.h>
#include <stdlib.h>
void swap(int* num1, int* num2)
{
int temp = *num1;
*num1 = *num2;
*num2 = temp;
}
//选择最大的在尾部
void SelectSort1(int arr[], int len)
{
for (int i = 0; i < len - 1; ++i)
{
int max = 0;
for (int j = 1; j < len - i; ++j)
{
if (arr[j] > arr[max])
{
max = j;
}
}
if (max != len - 1 - i)
{
swap(&arr[max], &arr[len - i - 1]);
}
}
}
//选择最小的放在头部
void SelectSort2(int arr[], int len)
{
for (int i = 0; i < len - 1; ++i)
{
int min = i;
for (int j = i + 1; j < len; ++j)
{
if (arr[j] < arr[min])
{
min = j;
}
}
swap(&arr[min], &arr[i]);
}
}
int main()
{
int beauties[] = { 163, 161, 158, 165, 171, 170, 163, 159, 162 };
int len = sizeof(beauties) / sizeof(beauties[0]);
SelectSort1(beauties, len);
//SelectSort2(beauties, len);
for (int i = 0; i < len; i++)
{
printf("%d ", beauties[i]);
}
system("pause");
return 0;
}
2、冒泡排序
#include<iostream>
#include<string>
using namespace std;
void swap(int& num1, int& num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
void bubbleSort(int arr[], int n)
{
for (int i = 0; i < n - 1; ++i)
{
for (int j = 0; j < n - i - 1; ++j)
{
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1]);
}
}
}
}
//优化一:这个优化可以通过在内层循环中添加一个标志来实现,如果没有发生交换,则排序提前结束。
void bubbleSortOptimized(int arr[], int n)
{
for (int i = 0; i < n - 1; ++i)
{
bool swapped = true;
for (int j = 0; j < n - i - 1; ++j)
{
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1]);
swapped = false;
}
}
if (swapped) break;
}
}
int main()
{
int beauties[] = { 163, 161, 158, 165, 171, 170, 163, 159, 162 };
int len = sizeof(beauties) / sizeof(beauties[0]);
//bubbleSort(beauties, len);
bubbleSortOptimized(beauties, len);
for (int i = 0; i < len; i++)
{
printf("%d ", beauties[i]);
}
system("pause");
return 0;
}
3、插入排序
#include<iostream>
#include<string>
using namespace std;
void InsertSort(int arr[], int len)
{
int current = 0;
int preIndex = 0;
for (int i = 1; i < len; ++i)
{
preIndex = i - 1;
current = arr[i];
while (preIndex >= 0 && arr[preIndex] > current)
{
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current; //此时preIndex=-1
}
}
int main(void) {
int beauties[] = { 163, 161, 158, 165, 171, 170, 163, 159,162 };
int len = sizeof(beauties) / sizeof(beauties[0]);
InsertSort(beauties, len);
printf("美女排序以后的结果是:\n");
for (int i = 0; i < len; i++)
{
printf("%d ", beauties[i]);
}
system("pause");
return 0;
}
4、希尔排序
#include <stdio.h>
#include <stdlib.h>
void ShellSort(int arr[], int len)
{
int gap = len / 2;
for (; gap > 0; gap = gap / 2)
{
for (int i = gap; i < len; ++i)
{
int current = arr[i];
int j = 0;
for (j = i - gap; j >= 0 && arr[j] > current; j = j - gap)
{
arr[j + gap] = arr[j];
}
arr[j + gap] = current;
}
}
}
int main(void)
{
int beauties[] = { 163, 161, 158, 165, 171, 170, 163, 1, 2 };
int len = sizeof(beauties) / sizeof(beauties[0]);
ShellSort(beauties, len);
printf("美女排序以后的结果是:\n");
for (int i = 0; i < len; i++)
{
printf("%d ", beauties[i]);
}
system("pause");
return 0;
}
5、堆排
#include <iostream>
#include <vector>
using namespace std;
//建立最大堆
void heapify(vector<int>& arr, int n, int i)
{
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
{
largest = left;
}
if (right < n && arr[right] > arr[largest])
{
largest = right;
}
if (largest != i)
{
swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
//堆排函数
void heapSort(vector<int>& arr)
{
int n = arr.size();
for (int i = n / 2 - 1; i >= 0; i--)
{
heapify(arr, n, i);
}
for (int i = n - 1; i > 0; --i)
{
swap(arr[i], arr[0]);
heapify(arr, i, 0);
}
}
int main() {
std::vector<int> arr = { 12, 11, 13, 5, 6, 7 };
int n = arr.size();
std::cout << "原始数组:";
for (int i = 0; i < n; i++)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
heapSort(arr);
std::cout << "堆排序后的数组:";
for (int i = 0; i < n; i++)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
return 0;
}
6、归并排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//void mergeAdd_demo(int arr[], int left, int mid, int right)
//{
// int temp[64] = { 0 };
// int i = left;
// int j = mid;
// int k = 0;
//
// while (i < mid && j <= right)
// {
// if (arr[i] < arr[j])
// {
// temp[k++] = arr[i++];
// }
// else
// {
// temp[k++] = arr[j++];
// }
// }
// while (i < mid)
// {
// temp[k++] = arr[i++];
// }
// while (j <= right)
// {
// temp[k++] = arr[j++];
// }
// memcpy(arr + left, temp, sizeof(int) * (right - left + 1));
//}
//并!
void mergeAdd(int arr[], int left, int mid,int right,int* temp)
{
int i = left;
int j = mid;
int k = left;
while (i < mid && j <= right)
{
if (arr[i] < arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
}
}
while (i < mid)
{
temp[k++] = arr[i++];
}
while (j <= right)
{
temp[k++] = arr[j++];
}
memcpy(arr + left, temp+left, sizeof(int) * (right - left + 1));
}
//归并排序 归!
void mergeSort(int arr[], int left, int right, int* temp)
{
int mid = 0;
if (left < right)
{
mid = left + (right - left) / 2;
mergeSort(arr, left, mid, temp);
mergeSort(arr, mid + 1, right, temp);
mergeAdd(arr, left, mid+1, right, temp); //mid+1 是右边的第一个**
}
}
int main(void)
{
int beauties[] = { 1,11, 15, 58 , 65 , 4, 8787, 8 };
int len = sizeof(beauties) / sizeof(beauties[0]);
int* temp = new int[len];
int mid = len / 2;
//mergeAdd(beauties,0, mid, len - 1,temp);
mergeSort(beauties, 0, len - 1, temp);
printf("执行归并后:\n");
for (int i = 0; i < len; ++i)
{
printf(" %d ", beauties[i]);
}
system("pause");
return 0;
}
7、快速排序
#include <stdio.h>
#include <stdlib.h>
int partition(int arr[], int low, int high)
{
int i = low;
int j = high;
int base = arr[low];
if (low < high)
{
while (i < j)
{
while (i < j && arr[j] >= base)
{
j--;
}
if (i < j) //右边已经找到小于基数的
{
arr[i++] = arr[j];
}
while (i < j && arr[i] < base)
{
i++;
}
if (i < j)
{
arr[j--] = arr[i]; //左边已经找到大于基数的
}
}
arr[i] = base;
}
return i;
}
//分支法 实现快速排序
void QuickSort(int* arr, int low, int high)
{
if (low < high)
{
int index = partition(arr, low,high);
QuickSort(arr, low, index - 1);
QuickSort(arr, index+1, high);
}
}
int main(void)
{
int arr[] = { 163, 161, 158, 165, 171, 170, 163, 159, 162 };
int len = sizeof(arr) / sizeof(arr[0]);
QuickSort(arr, 0, len - 1);
printf("执行快速排序后的结果:\n");
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
system("pause");
return 0;
}
查找算法:
**1、二分查找
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int int_compare(const void *key1, const void* key2)
{
const int* ch1 = (const int*)key1;
const int* ch2 = (const int*)key2;
return (*ch1 - *ch2);
}
int char_compare(const void *key1, const void *key2)
{
const char* ch1 = (const char*)key1;
const char* ch2 = (const char*)key2;
return (*ch1 - *ch2);
}
int BinarySearch(void* sorted, int len,int elemSize, void * search,int (*compare)(const void* key1, const void* key2))
{
int left = 0;
int right = len - 1;
int mid = 0;
while (left <= right)
{
int ret = 0;
mid = left + (right - left) / 2;
ret = compare((char*)sorted+(elemSize*mid), search);
if (ret==0)
{
return mid;
}
else if (ret>0)
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
return -1;
}
int main()
{
//整数型:
int arr[] = { 1,3,7,9,11 };
int search = 1;
int index = BinarySearch(arr, sizeof(arr) / sizeof(arr[0]),sizeof(int), &search, int_compare);
if (index ==-1)
{
cout << "没找到" << endl;
}
else
{
cout << "找到了! " << "索引为:" << index << endl;
}
//字符型:
char arr1[] = { 'a','c','d','f','j' };
char search1[] = { '0', 'a', 'e', 'j' , 'z' };
printf("\n 字符查找测试开始。。。\n");
for (int i = 0; i < sizeof(search1) / sizeof(search1[0]); i++)
{
int index = BinarySearch(arr1, sizeof(arr1) / sizeof(arr1[0]),sizeof(char), &search1[i], char_compare);
printf("searching %c, index: %d\n", search1[i], index);
}
}
2、穷举法:
#include <iostream>
using namespace std;
int main()
{
int a100 = 0;
int a50 = 0;
int a10 = 0;
int a5 = 0;
int cnt = 0;
for (int a100 = 0; a100 <= 10; a100++)
{
for (int a50 = 0; a50 <= 20; a50++)
{
for (int a10 = 0; a10 <= 20; a10++)
{
for (int a5= 0; a5 <= 20; a5++)
{
if (a100 * 100 + a50 * 50 + a10 * 10 + a5 * 5 == 1000 && a100 + a50 + a10 + a5 == 20)
{
cout << 100 << " " << 50 << " " << 10 << " " << 5 << " " << endl;
cout << a100 <<" " << a50 <<" " << a10 << " " << a5 << " " << endl;
cnt++;
}
}
}
}
}
cout << "方案共有:" << cnt << "种" << endl;
system("pause");
return 0;
}
3、并行搜索
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <time.h>
#define TEST_SIZE (1024*1024*200)
#define NUMBER 20
typedef struct _search
{
int* data; //搜索的数据集
size_t start; //搜索的开始位置
size_t end; //搜索的终止位置
size_t count; //搜索结果
}search;
DWORD WINAPI ThreadProc(void* lpParam)
{
search* s = (search*)lpParam;
time_t start, end;
printf("新的线程开始执行:\n");
time(&start);
for (int j = 0; j < 10; ++j)
{
for (int i = s->start; i <=s->end; ++i)
{
if (s->data[i] == NUMBER)
{
s->count++;
}
}
}
time(&end);
printf("查找所花费的时间:%lld \n", end - start);
return 0;
}
int main()
{
int* data = NULL;
int count = 0;
int mid = 0;
search s1, s2;
data = new int[TEST_SIZE];
for (int i = 0; i < TEST_SIZE; ++i)
{
data[i] = i;
}
mid = TEST_SIZE / 2;
s1.data = data;
s1.start = 0;
s1.end = mid - 1;
s1.count = 0;
s2.data = data;
s2.start = mid + 1;
s2.end = TEST_SIZE - 1;
s2.count = 0;
DWORD threadID1; //线程1的身份证
HANDLE hThread1; //线程1的句柄
DWORD threadID2; //线程2的身份证
HANDLE hThread2{}; //线程2的句柄
printf("创建线程。。。。。\n");
//创建线程1
hThread1 = CreateThread(NULL, 0, ThreadProc, &s1, 0, &threadID1);
//创建线程2
hThread1 = CreateThread(NULL, 0, ThreadProc, &s2, 0, &threadID2);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
printf("进程老爸欢迎线程归来!count:%d\n",s1.count+s2.count);
system("pause");
return 0;
}