以下是本人在学习数据结构与算法时的笔记
//数据结构与算法基础
-------------------------------------------------------
链表
struct Ploy{
int m_coe = 0;
int m_index = 0;
};
typedef struct LNode{
Ploy date;
LNode *prior = NULL;
LNode *next = NULL;
}LNode,*LinkList;
//建立链表
void setLinkList(LinkList &L){
LNode *p,*q;
q = L;
int coe,index,n;
cout << "输入n:";
cin >> n;
while (n--){
cin>>coe>>index;
if (index<0) break;
p = new LNode;
p->date.m_coe = coe;
p->date.m_index = index;
q->next = p;
q = q->next;
}
}
//合并链表
void combine(LinkList &L,LinkList &S,LinkList &T){
LNode *p,*q,*r;
p = L->next,q = S->next,r = T;
while (p && q){
if (p->date.m_index < q->date.m_index){
r ->next= p;
p = p->next;
r = r->next;
}else if (p->date.m_index > q->date.m_index){
r ->next= q;
q = q->next;
r = r->next;
}else{
p->date.m_coe+=q->date.m_coe;
if (p->date.m_coe==0){
LNode *s,*t;
s = p,t = q;
p = p->next;
q = q->next;
delete s;
delete t;
}else {
r->next = p;
LNode *s;
s = q;
q = q->next;
p = p->next;
r = r->next;
delete s;
}
}
}
r->next= p?p:q;
delete S;
S = NULL;
}
//打印链表
void printLinkList(LinkList &L){
LNode *p;
p = L->next;
while (p){
cout<date.m_coe<<" "<date.m_index<<" ";
p = p->next;
}
}
//尾指针循环链表
void CircleLinkList(LinkList &L){
LNode *p,*q;
q = L;
int n;
cout <<"输入尾指针循环链表长度n:";
cin >> n;
while (n--){
p = new LNode;
cin >> p->date.m_coe >> p->date.m_index;
q->next = p;
q = p;
}
q->next = L;
L = q;
}
//循环链表合并
void CombineCircleLinkList(LinkList &L,LinkList &S){
LNode *r;
r = L->next;
L->next = S->next->next;
S->next = r;
delete S->next;
}
//双向链表
void DoLinkList(LinkList &L){
LNode *p,*q;
q = L;
q->prior = NULL;
int n;
cout << "输入双向链表的长度n:";
cin >> n;
while (n--){
p = new LNode;
cin >> p->date.m_coe >> p->date.m_index;
p->prior = q;
q->next = p;
q = p;
}
//循环双向链表
// q->next = L;
// L->prior = q;
}
//------------------------------------------------------
//顺序栈
#define MAXSIZE 100
typedef struct {
int *base = NULL;
int *top = NULL;
int stackSize = 0;
}SqStack;
//初始化空栈
void initStack(SqStack &S){
S.base = new int[MAXSIZE];
if(S.base == NULL){
cout <<"内存分配失败!"<date = e;
p->next = S;
S = p;
}
//链栈的出栈
void Pop(LinkStack &S,int &e){
if (S == NULL){
cout << "链栈已空,无法出栈"<date;
p = S;
S = S->next;
delete p;
}
//取栈顶元素
int GetTop(LinkStack &S){
if (S==NULL){
cout << "栈为空"<date;
}
//--------------------------------------------------------------
//循环队列
#define QUEUEMAXSIZE 100
struct SqQueue{
int *base = NULL;
int front = 0;
int rear = 0;
};
//初始化队列
void initQueue(SqQueue &Q){
Q.base = new int[QUEUEMAXSIZE];
if (Q.base==NULL){
cout<<"内存分配失败"<next = NULL;
}
//销毁链队
void DestroyLinkQueue(LinkQueue &Q){
while (Q.front){
Q.rear = Q.front->next;
delete Q.front;
Q.front = Q.rear;
}
}
//入队
void EnLinkQueue(LinkQueue &Q,int e){
QNode *p;
p = new QNode;
if (p == NULL){
cout << "内存分配失败" << endl;
exit(-1);
}
p->date = e;
p->next = NULL;
Q.rear->next= p;
Q.rear = p;
}
//出对
void DeLinkQueue(LinkQueue &Q,int &e){
if (Q.front == Q.rear){
cout << "队列已空,出队失败" << endl;
exit(-1);
}
QNode *p;
p = Q.front->next;
e = p->date;
Q.front->next = p->next;
if (p == Q.rear) Q.rear = Q.front; //删除的是最后节点
delete p;
}
//取队列首元素
void GetHead(LinkQueue &Q,int &e){
if (Q.front == Q.rear){
cout << "队列已空,取元失败" << endl;
exit(-1);
}
e = Q.front->next->date;
}
//---------------------------------------------------------------
//串
//串的顺序储存结构
#define MAXLENGTH 255
typedef struct{
char ch[MAXLENGTH+1];
int length;
}SString;
//串的链式储存结构--块链
#define CHUNKSIZE 80
typedef struct Chunk{
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct{
Chunk *head,*tail;
int curlen; //串的当前长度
}LString;
//BF算法----暴力穷举法
int Index_BF(SString S,SString T){ //主串,子串
int i=1,j=1;
while (i<=S.length && j<=T.length){
if (S.ch[i]==T.ch[j]) i++,j++;
else {
i = i-j+2;
j = 1;
}
}
if (j>=T.length) return i-T.length;
else return 0;
}
//KMP算法
void get_next(SString T,int next[]){
int i=1,j=0;
next[1]=0;
while (iT.length) return i-T.length;
else return 0;
}
//--------------------------------------------------------------------
//二叉树
//总边数为 B B = n-1 = n2*2+n1*1
// n = n2*2+n1*1+1 又 n = n2+n1+n0
//即n0 = n2+1 叶子数目为度为2的结点数+1
//二叉树顺序储存表示
typedef int SqBiTree[MAXSIZE];
SqBiTree bt;
//二叉树链表储存结构
typedef struct BTNode{
int data;
BTNode *LChild,*RChild;//*parent
}BTNode,*BiTree;
//遍历二叉树
void visit(BiTree &T){
cout << T->data;
}
//先序 DLR 递归
void PreOrderTraverse(BiTree &T){
if(T==NULL) return;
else{
visit(T);
PreOrderTraverse(T->LChild);
PreOrderTraverse(T->RChild);
}
}
//中序 非递归
void InOrderTraverse(BiTree T){
SqStack S;
BiTree p,q;
initStack(S);
p = T;
while (p || !StackEmpty(S)){
if (p){
Push(S,p); //入栈
p = p->LChild;
}else{
Pop(S,q); //出栈
cout << q->data;
p = q->RChild;
}
}
}
//层次遍历
typedef struct{
BTNode data[MAXSIZE];
int front,rear;
}TreeSqQueue;
void LevelOrder(BTNode *b){
BTNode *p;
TreeSqQueue *qu;
initQueue(qu); //初始化队列
EnQueue(qu,b); //根结点指针进入队列
while (!QueueEmpty(qu)) { //队不为空,则循环
DeQueue(qu, p); //出队结点p
cout << p->data;
if (p->LChild != NULL) EnQueue(qu, p->LChild);
if (p->RChild != NULL) EnQueue(qu, p->RChild);
}
}
//建立二叉树
// A
// B
// C D
// E F
// G
//ABC##DE#G##F###
void CreateBiTree(BiTree &T){
char ch;
cin>>ch;
if (ch == '#') T = NULL;
else{
if (!(T = new BTNode)) exit(-1);
T->data = ch;
CreateBiTree(T->LChild);
CreateBiTree(T->RChild);
}
}
//复制二叉树
int Copy(BiTree T,BiTree &NewT){
if (T==NULL){
NewT = NULL;
return 0; //如果是空树返回0
}else{
NewT = new BTNode;
NewT->data = T->data;
Copy(T->LChild,NewT->LChild);
Copy(T->LChild,NewT->RChild);
return 1;
}
}
//计算二叉树深度
//n个结点时间复杂度为log2N+1
//左子树深度 m 与 右子树深度 n 的较大者 +1
int Depth(BiTree T){
int m,n;
if (T==NULL) return 0;
else {
m = Depth(T->LChild);
n = Depth(T->RChild);
return max(m,n)+1;
}
}
//计算二叉树结点
int NodeCount(BiTree T){
if (T==NULL) return 0;
else return NodeCount(T->LChild)+NodeCount(T->RChild)+1;
}
//计算二叉树叶子结点数
int LeadCount(BiTree T){
if (T==NULL) return 0;
else if (T->LChild==NULL && T->RChild==NULL) return 1;
else return LeadCount(T->LChild)+LeadCount(T->RChild);
}
//线索二叉树
//LTag(RTag) == 0 指向该结点的左(右)孩子
// 1 前驱(后继)
typedef struct BiThrNode{
int data;
int LTag,RTag;
BiThrNode *LChild,*RChild;
}BiThrNode,*BiThrTree;
//可增设一个头结点
//其LTag = 0,LChild指向根结点
//其RTag = 0,RChild指向遍历序列中最后一个结点
//遍历序列中第一个结点的LC域和最后一个结点的RC域都指向头结点
//------------------------------------------------------------
//树
//双亲表示法
//每个结点两个域 数据域 双亲域(双亲结点在数组中的位置)
typedef struct PTNode{
int data;
int parent;
} PTNode;
#define MAX_TREE_SIZE 100
typedef struct{
PTNode nodes[MAX_TREE_SIZE];
int r,n; //根结点位置和结点个数;
} PTree;
//孩子链表
//孩子结点结构
typedef struct CTNode{
int child;
CTNode *next;
} *ChildPtr;
//双亲结点结构
typedef struct{
int data;
ChildPtr firstChild; //孩子链表头指针
} CTBox;
//树结构
typedef struct {
CTBox nodex[MAX_TREE_SIZE];
int n,r;
}CTree; //可增加双亲域
//孩子兄弟表示法(二叉树表示法,二叉树链表表示法)
typedef struct CSNode{
int data;
CSNode *firstChild,*nextSibling;
} CSNode,*CSTree;
//将树转换为二叉树
//兄弟相连留长子 去掉原来右孩线
//森林转换为二叉树
//树变二叉根相连
//-------------------------------------
//哈夫曼树(最优二叉树):带权路径长度(WPL)最短的二叉树
//权:树中结点的数值
//结点的带权路径长度:根到该结点的 路径长度 与该结点的 权 的乘积
//数的带权路径长度:树中所有叶子结点的带权路径长度之和
//构造哈夫曼树:1、构造森林全是根 2、选用两小造新树
// 3、删除两小添新人 4、重复2、3剩单根
//哈夫曼构造算法的实现 采用顺序储存结构 共2n-1个结点
typedef struct{
int weight;
int parent,lch,rch;
} HTNode,*HuffmanTree;
//构造哈夫曼树
void select(HuffmanTree &HT,int len,int &s1,int &s2){
}
void CreatHuffmanTree (HuffmanTree &HT,int n){
if (n<=1) return;
int m = 2*n-1;
HT = new HTNode[m+1]; //0号单元未用 HT[m]表示根结点
for (int i = 1; i <= m; ++i) {
HT[i].lch = 0;
HT[i].rch = 0;
HT[i].parent = 0;
}
for (int i = 1; i <= n; ++i) {
cin >> HT[i].weight; //输入权
}
int s1,s2;
for (int i = n+1; i <= m; ++i) {
select(HT,i-1,s1,s2); //寻找两个最小结点的下标
HT[s1].parent = HT[s2].parent = i;
HT[i].lch = s1,HT[i].rch = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
}
//哈夫曼编码
typedef struct HuffmanCode{
char data;
char *code;
}*pHuffmanCode;
void CreatHuffmanCode(HuffmanTree HT,pHuffmanCode &HC,int n){
HC = new HuffmanCode[n+1];
char *cd;
cd = new char[n];
for (int i = 1; i <= n; ++i) {
int start = 0,c = i,f = HT[i].parent;
while (f!=0){
start++;
if (HT[i].lch == c) cd[start] = '0';
else cd[start] = '1';
c = f,f = HT[f].parent;
}
cd[++start] = '\0';
strrev(cd); //反转编码
HC[i].code = new char[start];
strcpy(HC[i].code,cd);
}
delete cd;
}
//-----------------------------------------------------------------------
//图
//邻接矩阵
#define MaxInt 32767 //表示极大值,即∞
#define MVNum 100 //最大顶点数
typedef struct{
char vex[MVNum]; //顶点表
int arcs[MVNum][MVNum]; //邻接矩阵
int vexNum,arcNum; //图的当前点数和边数
} AMGraph;
//创建无向网
int LocateVex(AMGraph &G,char v){
for (int i = 0; i < G.vexNum; ++i) {
if (G.vex[i] == v) return i;
}
return -1;
}
void CreateUDM(AMGraph &G){
cin >> G.vexNum >> G.arcNum; //总点数 总边数
for (int i = 0; i < G.vexNum; ++i) {
cin >> G.vex[i]; //输入点的信息
}
for (int i = 0; i < G.vexNum; ++i) {
for (int j = 0; j < G.vexNum; ++j) {
G.arcs[i][j] = MaxInt; //所有边的权置为极大值
}
}
char v1,v2;
int w;
for (int k = 0; k < G.arcNum; ++k) {
cin >> v1 >> v2 >> w; //一条边的两个顶点及边的权值
int i = LocateVex(G,v1);
int j = LocateVex(G,v2);
G.arcs[i][j] = w;
G.arcs[j][i] = G.arcs[i][j];
}
}
//------------------------------------------------------------
//邻接表
struct ArcNode{ //边结点
int adjVex; //该边所指向的顶点的位置
ArcNode *nextArc; //指向下一条边的指针
int info; //和边相关的信息
};
typedef struct VNode{
char data; //顶点信息
ArcNode *firstArc; //指向第一条依附该顶点的边的指针
} VNode,AdjList[MVNum];
typedef struct{
AdjList vertices;
int vexNum,arcNum;
} ALGraph;
//创建无向网
int LocateVex(ALGraph &G,char v){
for (int i = 0; i < G.vexNum; ++i) {
if (G.vertices[i].data == v) return i;
}
return -1;
}
void CreateUDG(ALGraph &G){
cin >> G.vexNum >>G.arcNum;
for (int i = 0; i < G.vexNum; ++i) {
cin >> G.vertices[i].data;
G.vertices[i].firstArc = NULL;
}
char v1,v2;
for (int k = 0; k < G.arcNum; ++k) {
cin >> v1 >> v2;
int i = LocateVex(G,v1);
int j = LocateVex(G,v2);
ArcNode *p1,*p2;
p1 = new ArcNode;
p1->adjVex = j;
p1->nextArc = G.vertices[i].firstArc; //头插法
G.vertices[i].firstArc = p1;
p2 = new ArcNode;
p2->adjVex = i;
p2->nextArc = G.vertices[j].firstArc;
G.vertices[j].firstArc = p2;
}
}
//邻接矩阵多用于稠密图 邻接表多用于稀疏图
//采用 邻接矩阵 表示图的 深度优先 搜索遍历
int visited[100]; //第i个顶点已访问则 visited[i] = 1;否则为0;
void DFS(AMGraph G,int v){
cout << v;
visited[v] = true;
for (int w = 0; w < G.vexNum; ++w) {
if (G.arcs[v][w]!=0 && visited[w]==0){ //w是v的邻接点且w为2访问
DFS(G,w);
}
}
}
//广度优先
int FirstAdjVex(ALGraph G,int u){
return G.vertices[u].firstArc->adjVex;
}
int NextAdjVex(ALGraph G,int u,int w){
ArcNode *p;
p = G.vertices[u].firstArc;
while (w != p->adjVex){
p = p->nextArc;
}
if (p->nextArc == NULL) return -1;
else return p->nextArc->adjVex;
}
void BFS(ALGraph G,int v){
cout << v;
visited[v] = true;
SqQueue Q;
initQueue(Q);
EnQueue(Q,v);
int u;
while (!QueueEmpty(Q)){
DeQueue(Q,u);
for (int w = FirstAdjVex(G,u); w >= 0; w = NextAdjVex(G,u,w)) {
if (visited[w]==0){
cout << w;
visited[w] = true;
EnQueue(Q,w);
}
}
}
}