一、顺序表
顺序表结构体定义
typedef struct{
int data[maxsize];
int length;
}SqList;
1.顺序表递增有序,插入元素x,仍递增有序
void insert(SqList &L, int x){
for(int i=0; i<L.length; i++){
if(L.data[i] >= x){
for(int j=L.length; j>i; j--){
L.data[j] = L.data[j-1];
}
L.data[i] = x;
L.length++;
break;
}
}
}
2.用顺序表最后一个元素覆盖整个顺序表中最小元素,并返回该最小元素
int cover(SqList &L){
int min = 0;
for(int i=1; i<L.length; i++){
if(L.data[i] < L.data[min]){
min = i;
}
}
int minvalue = L.data[min];
L.data[min] = L.data[length-1];
L.length--;
return minvalue;
}
3.将顺序表中的元素逆置
void reserve(SqList &L){
int temp;
for(int i=0; i<L.length/2; i++){
temp = L.data[i];
L.data[i] = L.data[length-1-i];
L.data[length-1-i] = temp;
}
}
4.删除顺序表中所有值为x的元素(喝前摇一摇,考前看一看)
思想:删除顺序表中所有值为x的元素等价于保留顺序表中所有值不为x的元素
void delete(SqList &L, int x){
int k = 0;
for(int i=0; i<L.length; i++){
if(L.data[i] != x){
L.data[k++] = L.data[i];
}
}
L.length = k;
}
5.从顺序表中删除给定值在s到t之间(包含s和t)的所有元素
void delete(SqList &L, int s, int t){
int k = 0;
for(int i=0; i<L.length; i++){
if(L.data[i]<s || L.data[i]>t){
L.data[k] = L.data[i];
k++;
}
}
L.length = k;
}
6.从有序表中删除所有值重复的元素(喝前摇一摇,考前看一看)
思想:从有序表中删除所有值重复的元素等价于保留第一个不重复的元素
void delete(SqList &L){
int i,j;
for(i=0;j=1; j<L.length; j++){
if(L.data[i] != L.data[j]){
L.data[++i] = L.data[j];
}
}
L.length = i+1;
}
7.两个递增有序表合并成一个递增有序表(喝前摇一摇,考前看一看)
void union(SqList L1, SqList L2, SqList &L3){
int i=0; j=0; k=0;
while(i<L1.length && j<L2.length){
if(L1.data[i] < L2.data[j]){
L3.data[k++] = L1.data[i++];
}else {
L3.data[k++] = L2.data[j++];
}
}
while(i<L1.length){
L3.data[k++] = L1.data[i++];
}
while(j<L2.length){
L3.data[k++] = L2.data[j++];
}
L3.length = k;
}
8.设计一个时间上尽可能高效的算法,找出数组中未出现的最小正整数(喝前摇一摇,考前看一看)
int min(int A[], int n){
int *B = new int[n+1];
int i;
for(i=0; i<n+1; i++){
B[i] = 0;
}
for(i=0; i<n+1; i++){
if(A[i]>0 && A[i]<=n){
B[A[i]] = A[i];
}
}
for(i=1; i<n+1; i++){
if(B[i] == 0){
break;
}
}
delete[] B;
return i;
}
二、链表
链表结构体定义
typedef struct LNode{
int data;
struct LNode *next;
}LNode, *LinkList;
1.设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
void delete(LNode *&L, int x){
LNode *p;
if(L == NULL){
return;
}
if(L->data == x){
p = L;
L = L->next;
free(p);
delete(L, x);
}else{
delete(L->next, x);
}
}
2.删除带头结点单链表中所有值为x的结点
void delete(LNode *&L, int x){
LNode *p = L;
while(p->next != NULL){
if(p->next->data == x){
LNode *q = p->next;
p->next = q->next;
free(q);
}else{
p = p->next;
}
}
}
3.删除单链表中第一个值为x的元素
int delete(LNode *&L, int x){
LNode *p = L;
while(p->next != NULL){
if(p->next->data == x){
LNode *q = p->next;
p->next = q->next;
free(q);
break;
}else{
p = p->next;
}
}
}
4.试编写算法将单链表就地逆置
思路:头插法
void reserve(LNode *&L){
LNode *p = L->next;
LNode *r;
L->next = NULL;
while(p != NULL){
r = p->next;
p->next = L->next;
L->next = p;
p = r;
}
}
5.试编写在带头结点的单链表L中删除最小值点的高效算法(已知最小值唯一)
void delete(LNode *L){
LNode *p = L;
LNode *minp = L;
while(p->next != NULL){
if(p->next->data < minp->next->data){
minp = p;
}
p = p->next;
}
LNode *q = minp->next;
minp->next = q->next;
free(q);
}
6.试编写在不带头结点的单链表L中删除最小值点的高效算法(已知最小值唯一)(喝前摇一摇,考前看一看)
void delete(LNode *L){
LNode *minp = L;
LNode *p = L->next;
while(p != NULL){
if(p->data < minp->data){
minp = p;
}
p = p->next;
}
if(L == minp){
L = L->next;
free(L);
return;
}
p = L;
while(p->next != minp){
p = p->next;
}
p->next = minp->next;
free(minp);
}
7.给定一个单链表,按递增排序输出单链表中各结点的数据元素,并释放结点所占空间
void print(LNode *L){
while(L->next != NULL){
LNode *p = L;
LNode *minp = L;
while(p->next != NULL){
if(p->next->data < minp->next->data){
minp = p;
}
p = p->next;
}
cout << minp->next->data << "";
LNode *q = minp->next;
minp->next = q->next;
free(q);
}
free(L);
}
8.将一个带头结点的单链表A分解成两个带头结点的单链表A和B,使A中含奇数位置元素,B中含偶数位置元素,且相对位置不变
LNode *separate(LNode *&A){
LNode *p = A->next;
LNode *r1 = A;
A->next = NULL:
LNode *B = (LinkList)malloc(sizeof(LNode));
LNode *r2 = B;
B->next = NULL;
LNode *r;
int i = 1;
while(p != NULL){
if(i%2 != 0){
r = p->next;
p->next = r1->next;
r1->next = p;
r1 = r1->next;
p = r;
}else{
r = p->next;
p->next = r2->next;
r2->next = p;
r2 = r2->next;
p = r;
}
i++;
}
return B;
}
9.删除递增链表中重复的元素
void delete(LNode *&L){
LNode *p = L->next;
while(p != NULL){
LNode *pre = p;
LNode *q = p->next;
while(q != NULL){
if(q->data == p->data){
pre->next = q->next;
free(q);
q = pre->next;
}else{
pre= pre->next;
q = q->next;
}
}
p = p->next;
}
}
10.两个递增有序的单链表,设计算法将两个链表合并成一个非递减有序的链表(喝前摇一摇,考前看一看)
void union(LNode *&A, LNode *&B){
LNode *p = A->next;
A->next = NULL;
LNode *r = A;
LNode *q = B->next;
LNode *r1
while(p != NULL && q != NULL){
if(p->data < q->data){
r1 = p->next;
p->next = r->next;
r->next = p;
r = r->next;
p = r1;
}else{
r1 = q->next;
q->next = r->next;
r->next = q;
r = r->next;
q = r1;
}
}
if(p != NULL){
r->next = p;
}
if(q != NULL){
r->next = q;
}
}
11.A,B两个单链表递增有序,从A,B中找出公共元素产生单链表C,要求不破坏A,B结点
LNode *common(LNode *A, LNode *B){
LNode *p = A->next;
LNode *q = B->next;
LNode *C = (LinkList)malloc(sizeof(LNode));
C->next = NULL;
LNode *r = C;
LNode s;
while(p!=NULL && q!=NULL){
if(p->data < q->data){
p = p->next;
}else if(q->data < p->data){
q = q->next;
}else{
s = (LNode *)malloc(sizeof(LNode));
s->data = p->data;
r->next = s;
r = s;
p = p->next;
q = q->next;
}
}
r->next = NULL;
return C;
}
12.查找单链表中倒数第k个结点,若成功,则输出该结点的data,并返回1,否则返回0
int find(LNode *L, int k){
LNode *p = L->next;
LNode *q = L->next;
int i = 0;
while(p!=NULL && i<k){
q = q->next;
i++;
}
if(i != k){
return 0;
}
while(q != NULL){
p = p->next;
q = q->next;
}
cout << p->data << "";
return 1;
}
13.用单链表保存m个整数,并且|data|<=n,要求设计时间复杂度尽可能高效的算法,对于data绝对值相等的点,仅保留第一次出现的点(喝前摇一摇,考前看一看)
void func(LNode *&L, int n){
LNode *p = L;
int *A = new int[n+1];
for(int i=0 ;i<n+1; i++){
A[i] = 0;
}
int m;
LNode *q;
while(p->next != NULL){
m = abs(p->next->data);
if(A[m] == 0){
A[m] = 1;
p = p->next;
}else{
q = p->next;
p->next = q->next;
free(q);
}
}
free(A);
}
14.判断带头结点的循环双链表是否对称
bool func(LNode *L){
LNode *p = L->next;
LNode *q = L->prior;
while(p!=q && q->next!=p){
if(p->data != q->data){
return false;
}
p = p->next;
q = q->prior;
}
return true;
}
15.有两个循环单链表,链表头指针分别为h1,h2,试编写函数将h2链表接到h1之后,要求链接后仍保持循环链表形式(喝前摇一摇,考前看一看)
void link(LNode *&h1, LNode *&h2){
LNode *p = h1;
LNode *q = h2;
while(p->next != h1){
p = p->next;
}
while(q->next != h2){
q = q->next;
}
q->next = h1;
p->next = h2;
}
16.设有一个带头结点的循环单链表,其结点值为正整数,设计算法反复找出链表内最小值并不断输出,并将结点从链表中删除,直到链表为空,再删除表头结点
void delete(LNode *L){
while(L->next != L){
LNode *p = L;
LNode *minp = L
while(p->next != L){
if(p->next->data < minp->next->data){
minp = p;
}
}
cout << minp->next->data << "";
LNode *q = minp->next;
minp->next = q->next;
free(q);
}
free(L);
}
17.判断单链表是否有环(喝前摇一摇,考前看一看)
int func(LNode *L){
LNode *fast = L;
LNode *slow = L;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
return 1;
}
}
return 0;
}
三、栈和队列
栈的结构体
typedef struct{
char data[maxsize];
int top;
}Stack;
队列的结构体
typedef strcut{
int data[maxsize];
int front, rear;
}Queue;
1.S是一个空栈,Q是一个队列,编写算法使得队列中元素逆置(喝前摇一摇,考前看一看)
void reserve(Stack &S, Queue &Q){
while(Q.front != Q.rear){
push(S, dequeue(Q));
}
while(S.top != -1){
enqueue(Q, pop(S));
}
}
2.判断单链表的全部n个字符是否中心对称
bool func(LNode *L){
Stack S;
int top = -1;
LNode *p = L->next;
while(p != NULL){
S.data[++S.top] = p->data;
p = p->next;
}
p = L->next;
while(S.top != -1){
if(p->data != S.data[S.top--]){
return false;
}
}
return true;
}
3.两个栈S1,S2都采用顺序存储,并共享一个存储区[0,...,maxsize-1]。采用栈顶相向,迎面增长的存储方式,设计S1,S2入栈和出栈操作(喝前摇一摇,考前看一看)
bool push(Stack &S, int i, int x){
if(i<0 || i>1){
return false;
}
if(s.top[1]-s.top[0] == 1){
return false;
}
if(i == 0){
S.data[++S.top[0]] = x;
}else if(i == 1){
S.data[--S.top[1]] = x;
}
return true;
}
bool pop(Stack &S, int i){
if(i<0 || i>1){
return false;
}
if(i == 0){
if(S.top[0] == -1){
return false;
}else{
return S.data[S.top[0]--]
}
}else if(i == 1){
if(S.top[1] == maxsize){
return false;
}else{
S.data[S.top[1]++];
}
}
return true;
}
4.判断一个表达式中括号是否配对(假设只包含圆括号)(喝前摇一摇,考前看一看)
bool func(Stack S, String str){
int i = 0;
while(str[i] != '\0'){
if(str[i]=='('){
push(S,'(');
}
if(str[i]==')'){
if(pop(S)!='('){
return false;
}
}
i++;
}
if(S.top == -1){
return true;
}else{
return false;
}
}
四、树
树的结构体
typedef struct BTNode{
char data;
struct BTNode *lchild, *rchild;
}BTNode, *BiTree;
1.计算二叉树中所有结点个数
void count(BTNode *p, int &n){
if(p != NULL){
++n;
count(p->lchild, n);
count(p->rchild, n);
}
}
2.计算二叉树中所有叶子结点个数
void count(BTNode *p, int &n){
if(p != NULL){
if(!p->lchild && !p->rchild){
n++;
}
count(p->lchild, n);
count(p->rchild, n);
}
}
3.计算二叉树中所有双分支的结点个数
void count(BTNode *p, int &n){
if(p != NULL){
if(p->lchild && p->rchild){
n++;
}
count(p->lchild, n);
count(p->rchild, n);
}
}
4.计算二叉树的深度
int deep(BTNode *p){
if(p == NULL){
return 0;
}
int left = deep(p->lchild);
int right = deep(p->rchild);
if(left > right){
return left + 1;
}else{
return right +1
}
}
5.(a-(b+c)*(d/e))存储在二叉树,遍历二叉树求出表达式,遍历二叉树求表达式的值
void getbda(BTNode *p, int &deep){
if(p != NULL){
if(p->lchild && p->rchild && deep>1){
cout << "(";
}
deep++;
getbds(p->lchild);
cout << p->data << "";
getbds(p->rchild);
deep--;
if(p->lchild && p->rchild && deep>1){
cout << ")";
}
}
}
int getvalue(BTNode *p){
if(p == NULL){
return 0;
}
if(p->lchild && p->rchild){
int left = getvalue(p->lchild);
int right = getvalue(p->rchild);
reutn op(left, right, p->data);
}
if(!p->lchild && !p->rchild){
return p->data - '0';
}
}
6.找出二叉树中最大值的点
void getmax(BTNode *p, int &max){
if(p != NULL){
if(p->data > max){
max = p->data;
}
getmax(p->lchild, max);
getmax(p->rchild, max);
}
}
7.查找二叉树中data域等于key的结点是否存在,若存在,将q指向它,否则q为空
void func(BTNode *p, int key, BTNode *&q){
if(p != NULL){
if(p->data == key){
q = p;
}
func(p->lchild, key, q);
func(p->rchild, key, q);
}
}
8.输出先序遍历第k个结点的值
void print(BTNode *p, int k, int &n){
if(p != NULL){
if(n == k){
cout << p->data << "";
return;
}
n++;
print(p->lchild, k, n);
print(p->rchild, k, n);
}
}
9.求二叉树中值为x的层号(喝前摇一摇,考前看一看)
void func(BTNode *p, int x, int &n){
if(p != NULL){
if(p->data == x){
cout << n <<"";
}
n++;
func(p->lchild, x, n);
func(p->rchild, x, n);
n--;
}
}
10.树中元素为x的结点,删除以它为根的子树
void delete(BTNode *&p, int x){
if(p != NULL){
if(p->data == x){
p == NULL;
return;
}
delete(p->lchild, x);
delete(p->rchild, x);
}
}
11.利用结点的右孩子指针将一个二叉树的叶子结点从左向右连接成一个单链表(head指向第一个,tail指向最后一个)
void func(BTNode *p, BTNode *&head, BTNode *&tail){
if(p != NULL){
if(!p->lchild && !p->rchild){
if(head == NULL){
head = p;
tail = p;
}else{
tail->rchild = p;
tail = p;
}
}
func(p->lchild, head, tail);
func(p->rchild, head, tail);
}
}
12.先序非递归遍历二叉树(喝前摇一摇,考前看一看)***
void nonpre(BTNode *p){
BTNode *stack[maxsize];
int top = -1;
while(p ||top!=-1){
if(p){
cout << p->data << "";
stack[++top] = p;
p = p->lchild;
}else{
p = stack[top--];
p = p->rchild;
}
}
}
12.中序非递归遍历二叉树(喝前摇一摇,考前看一看)***
void nonmid(BTNode *p){
BTNode *stack[maxsize];
int top = -1;
while(p || top=-1){
if(p){
stack[++top] = p;
p = p->lchild;
}else{
p = stack[top--];
cout << p->data << "";
p = p->rchild;
}
}
}
13.后序非递归遍历二叉树(喝前摇一摇,考前看一看)***
void nonpost(BTNode *p, BTNode *tag){
BTNode *stack[maxsize];
int top = -1;
tag == NULL;
while(p || top!=-1){
if(p){
stack[++top] = p;
p = p->lchild;
}else{
p = stack{top};
if(p->rchild && p->rchild!=tag){
p = p->rchild;
}else{
p = stack[top--];
cout << p->data << "";
tag = p;
p = NULL;
}
}
}
}
14.在二叉树中查找值为x的结点,打印出值为x的所有祖先(喝前摇一摇,考前看一看)
void nonpost(BTNode *p, BTNode *tag){
BTNode *stack[maxsize];
int top = -1;
tag = NULL;
while(p || top!=-1){
if(p){
stack[++top] = p;
p = p->lchild;
}else{
p = stack[top];
if(p->rchild && p->rchild!=tag){
p = p->rchild;
}else{
p = stack[top--];
if(p->data == x){
while(top != -1){
cout << stack[top--] << "";
}
}
tag = p;
p = NULL;
}
}
}
}
15.层次遍历(喝前摇一摇,考前看一看)
void level(BTNode *p){
BTNode *queue[maxsize];
int front = 0;
int rear = 0;
if(p){
queue[rear++] = p;
while(front != rear){
p = queue[front++];
cout << p->data << "";
if(p->lchild){
queue[rear++] = p->lchild;
}
if(p->rchild){
queue[rear++] = p->rchild;
}
}
}
}
16.试给出自下而上从右向左的层次遍历
void level(BTNode *p){
BTNode *stack[maxsize];
int top = -1;
BTNode *queue[maxsize];
int front = 0;
int rear = 0;
if(p){
queue[rear++] = p;
while(front != rear){
p = queue[front++];
stack[++top] = p;
if(p->lchild){
queue[rear++] = p->lchild;
}
if(p->rchild){
queue[rear++] = p->rchild;
}
}
while(top != -1){
cout << stack[top--]->data << "";
}
}
}
17.判断二叉树是否为完全二叉树(喝前摇一摇,考前看一看)***
bool func(BTNode *p){
BTNode *que[maxsize];
int front = 0;
int rear = 0;
if(p == NULL){
return true;
}
que[rear++] = p;
while(front != rear){
p = que[front++];
if(p != NULL){
que[rear++] = p->lchild;
que[rear++] = p->rchild;
}else{
while(front != rear){
p = que[front++];
if(p == NULL){
return false;
}
}
}
}
return true;
}
18.计算二叉树的带权路径长度(叶子结点)(喝前摇一摇,考前看一看)***
int func(BTNode *p, int deep){
if(p == NULL){
return 0;
}
if(!p->lchild && !p->rchild){
return deep*(p->data-'0');
}
int A = func(p->lchild, deep+1);
int B = func(p->rchild, deep+1);
return A + B;
}
19.用孩子兄弟表示法求树中所有叶子结点的个数(喝前摇一摇,考前看一看)再看一遍视频
思想:孩子兄弟表示法中的叶子结点即左孩子为空的结点
int func(BTNode *p){
if(p == NULL){
return 0;
}
if(p->lchild == NULL){
return 1+func(p->rchild);
}
int A = func(p->lchild);
int B = func(p->rchild);
return A + B;
}
20.用孩子兄弟表示法求树的高度(喝前摇一摇,考前看一看)再看一遍视频
void func(BTNode *p, int n, int &max){
if(T != NULL){
if(max < n){
max = n;
}
func(T->lchild, n+1, max);
func(T->rchild, n, max);
}
}
五、图
图的结构体之邻接表
typedef struct ArcNode{
int adjvex;
struct ArcNode *nextarc;
}ArcNode, *Node;
typedef struct{
int data;
ArcNode *firstarc;
}VNode;
typedef struct{
VNode adjlist[maxsize];
int numvex, numedg;
}AGraph;
图的结构体之邻接矩阵
typedef struct{
int verticle[maxsize];
int edge[maxsize][maxsize];
int numvex, numedg;
}MGraph;
1.头插法建立图(邻接表结构体)
AGraph *func(int v, int e){
AGraph *G = new AGraph;
G->numvex = v;
G->numedg = e;
for(int i=0; i<G->numver; i++){
G->adjlist[i].firstarc = NULL;
}
for(int i=0; i<G->numedg; i++){
int v1, v2;
cin >> v1;
cin >> v2;
ArcNode *p = new ArcNode;
p->adjvex = v1;
p->nextarc = G->adjlist[v2].firstarc;
G->adjlist[v2].firstarc = p;
ArcNode *q = new ArcNode;
q->adjvex = v2;
q->nextarc = G->adjlist[v1].firstarc;
G->adjlist[v1].firstarc = q;
}
return G;
}
2.判断无向图中是否存在EL路径
int isExistEL(MGraph G){
int degree;
int count = 0;
for(int i=0; i<G.numVertices; i++){
degree = 0;
for(int j=0; j<G.numVertives; j++){
if(G.Edge[i][j] != 0){
degree++;
}
}
if(degree%2 != 0){
count++;
}
}
if(count==0 || count==2){
return 1;
}else{
return 0;
}
}
3.树的层次遍历
void level(BTNode *p){
BTNode *que[maxsize];
int front = 0;
int rear = 0;
if(p != NULL){
que[rear++] = p;
while(front != rear){
p = que[front++];
cout << p->data << "";
if(p->lchild != NULL){
que[rear++] = p->lchild;
}
if(p->rchild != NULL){
que[rear++] = p->rchild;
}
}
}
}
4.图的广度优先遍历(喝前摇一摇,考前看一看)***
void BFS(AGraph *G, int v, int visit[]){
for(int i=0; i<G->numver; i++){
visit[i] = 0;
}
int que[maxsize];
int front = 0;
int rear = 0;
cout << v <<"";
visit[v] = 1;
que[rear++] = v;
ArcNode *p;
while(front != rear){
v = que[front++];
p = G->adjlist[v].firstarc;
while(p != NULL){
if(visit[p->adjvex] == 0){
cout << p->adjvex << "";
visit[p->adjvex] = 1;
que[rear++] = p->adjvex;
}
p = p->nextarc;
}
}
}
5.利用BFS求无向图的最短路径
void BFSMin(AGraph *G, int v, int visit[], int d[]){
for(int i=0; i<G->numver; i++){
visit[i] = 0;
}
for(int i=0; i<G->numver; i++){
d[i] = INT_MAX;
}
int que[maxsiz];
int front = 0;
int rear = 0;
visit[v] = 1;
d[v] = 0;
que[rear++] = v;
ArcNode *p;
while(front != rear){
v = que[front++];
p = G->adjlist[v].firstarc;
while(p != NULL){
if(visit[p->adjvex] == 0){
d[p->adjvex] = d[v]+1;
visit[p->adjvex] = 1;
que[rear++] = p->adjvex;
}
p = p->nextarc;
}
}
}
6.图的深度优先遍历(喝前摇一摇,考前看一看)***
void init(AGraph *G, int visit[]){
for(int i=0; i<G->numver; i++){
visit[i] = 0;
}
}
void DFS(AGraph *G; int v; int visit[]){
cout << v << "";
visit[v] = 1;
ArcNode *p = G->adjlist[v].firstarc;
while(p != NULL){
if(visit[p->adjvex] == 0){
DFS(G, p->adjvex, visit);
}
p = p->nextarc;
}
}
void main(AGraph *G, int v, int visit[]){
init(G, visit);
DFS(G, v, visit);
}
7.判断图中i和j结点之间是否有路径
void ispath(AGraph *G, int visit[], int i, int j){
for(int i=0; i<G->numver; i++){
visit[i] = 0;
}
DFS(G, i, visit);
if(visit[j] == 1){
return true;
}else{
return false;
}
}
8.求无向图的连通分量个数
int count(AGraph *G, int v, int visit[]){
for(int i=0; i<G->numver; i++){
visit[i] = 0;
}
int count = 0;
for(int i=0; i<G->numver; i++){
if(visit[v] == 0){
DFS(G, v, visit);
count++;
}
}
return count;
}
9.图的深度优先遍历非递归算法(喝前摇一摇,考前看一看)***
void nonDFS(AGraph *G, int v, int visit[]){
for(int i=0; i<G->numver; i++){
visit[i] = 0;
}
int stack[maxsize];
int top = -1;
cout << v << "";
visit[v] = 1;
stack[++top] = v;
ArcNode *p;
while(top != -1){
v = stack[top];
p = G->adjlist[v].firstarc;
while(p && visit[p->adjvex]==1){
p = p->nextarc;
}
if(p == NULL){
top--;
}else{
cout << p->adjvex << "";
visit[p->adjvex] = 1;
stack[++top] = p->adjvex;
}
}
}
10.邻接表转化成邻接矩阵
void invert(AGraph *G1, MGraph G2){
G2.numver = G1->numver;
G2.numedg = G1->numedg;
ArcNode *p;
for(int i=0; i<G1->numver; i++){
G2.vertices[i] = G1->adjlist[i];
p = G1->adjlist[i].firstarc;
while(p != NULL){
G2.edge[i][p->adjvex] = 1;
p = p->nextarc;
}
}
}
11.邻接矩阵变成邻接表(头插法)
void invert(MGraph G1, AGraph *G2){
G2->numver = G1.numver;
G2->numedg = G1.numedg;
ArcNode *p;
for(int i=0; i<G1.numver; i++){
G2->adjlist[i]->firstarc = NULL;
}
for(int i=0; i<G1.numver; i++){
for(int j=0; j<G2.numver; j++){
if(G1.edge[i][j] != 0){
p = new ArcNode;
p->adjvex = j;
p->nextarc = G2->adjlist[i].firstarc;
G2->adjlist[i].firstarc = p;
}
}
}
}
六、查找
1.顺序表递增有序,设计算法在最少的时间内查找值为x的元素。若找到,则将其与后继元素交换位置,否则按照递增顺序插入顺序表(喝前摇一摇,考前看一看)
void search(SqList &L, int x){
int low = 0;
int high = L.length - 1;
int mid, temp, i;
while(low <= high){
mid = (low+high)/2;
if(x == L.data[mid]){
break;
}else if(x < L.data[mid]){
high = mid - 1;
}else{
low = mid + 1;
}
}
if(L.data[mid]==x && mid != L.length-1){
temp = L.data[mid+1];
L.data[mid+1] = L.data[mid];
L.data[mid] = temp;
}
if(low > high){
for(i=L.length-1; i>high; i--){
L.data[i+1] = L.data[i];
}
L.data[i+1] = x;
L.length++;
}
}
2.在顺序表中二分查找值为key的元素位置
int search(SqList L, int key){
int low = 0;
int high = L.length-1;
int mid;
while(low <= high){
mid = (low+high)/2;
if(key == L.data[mid]){
return mid+1;
}else if(key < L.data[mid]){
high = mid - 1;
}else{
low = mid + 1;
}
}
return -1;
}
3.判断给定二叉树是否是二叉排序树(喝前摇一摇,考前看一看)
int judgeBST(BTNode *p, int &pre){
if(p == NULL){
return 1;
}
int left = judgeBST(p->lchild, pre);
if(p->data<=pre || left==0){
return 0;
}else{
pre = p->data;
}
int right = judgeBST(p->rchild, pre);
return right;
}
4.寻找二叉排序树中的最大值和最小值
BTNode *min(BTNode *p){
while(p->lchild != NULL){
p = p->lchild;
}
return p
}
BTNode *max(BTNode *p){
while(p->rchild != NULL){
p = p->rchild;
}
return p;
}
5.求出指定结点在给定二叉排序树的层次(喝前摇一摇,考前看一看)
int level(BTNode *p, int k){
int n = 1;
BTNode *t = p;
if(p != NULL){
while(t->data != k){
if(t->data < k){
t = t->rchild;
}else{
t = t->lchild;
}
n++;
}
}
return n;
}
6.输出二叉搜索树中所有值大于key的结点
void func(BTNode *p, int key){
if(p != NULL){
func(p->lchild, key);
if(p->data >= key){
cout << p->data << "";
}
func(p->rchild, key);
}
}
7.判断一个二叉树是否为平衡二叉树(喝前摇一摇,考前看一看)
int judgeAVL(BTNode *p){
if(p == NULL){
return 0;
}
int left = judgeAVL(p->lchild);
int right = judgeAVL(p->rchild);
if(left==-1 || right==-1 || abs(left-right)>1{
return -1;
}else{
return max(left,right) + 1;
}
}
bool main(BTNode *p){
if(func(p) == -1){
return false;
}else{
return true;
}
}
七、排序
1.直接插入排序之顺序存储
void insertSort(int A[], int n){
int i, j, temp;
for(i=2; i<=n; i++){
A[0] = A[i];
for(j=i-1; A[0]<A[j]; j--){
A[j+1] = A[j];
}
A[j+1] = A[0];
}
}
2.直接插入排序之链式存储(喝前摇一摇,考前看一看)***
void linkSort(LNode *&L){
LNode *p = L->next;
LNode *r = p->next;
p->next = NULL;
p = r;
while(p != NULL){
r = p->next;
LNode *pre = L;
while(pre->next != NULL && pre->next->data < p->data){
pre = pre->next;
}
p->next = pre->next;
pre->next = p;
p = r;
}
}
3.折半插入排序(喝前摇一摇,考前看一看)
折半查找条件是: low<=high
快速排序条件是: low<high
void binSearch(int A[], int &low, int &high, int key){
int mid;
while(low <= high){
mid = (low+high)/2;
if(key < mid){
high = mid - 1;
}else if(key >= mid){
low = mid + 1;
}
}
}
void binSort(int A[], int n){
int low, high;
for(int i=2; i<n; i++){
A[0] = A[i];
low=1, high=i-1
binSearch(A, low, high, A[0]);
for(int j=i-1; j<=high+1; j--){
A[j+1] = A[j];
}
A[high+1] = A[0];
}
}
4.冒泡排序(递增排序)(喝前摇一摇,考前看一看)
void bubbleSort(int A[], int n){
int i, j, flag;
for(i=n-1; i>0; i--){
flag = 0;
for(j=1; j<=i; j++){
if(A[j-1] > A[j]){
swap(A[j-1], A[j]);
flag = 1;
}
}
if(flag == 0){
return;
}
}
}
5.快速排序(喝前摇一摇,考前看一看)
int part(int A[], int low, int high){
int pivot = A[low];
while(low < high){
while(low<high && A[high]>pivot){
high--;
}
A[low] = A[high];
while(low<high && A[low]<pivot){
low++;
}
A[high] = A[low];
}
A[low] = pivot;
return low;
}
void quickSort(int A[], int low, int high){
if(low < high){
int pivotpos = part(A, low, high);
quickSort(A,low, pivotpos-1);
quickSort(A,pivotpos+1,high);
}
}
6.选择排序
void selectSort(int A[], int n){
int min;
for(int i=0; i<n; i++){
min = i;
for(int j=i+1; j<n; j++){
if(A[j] < A[i]){
min = j;
}
}
swap(A[i], A[min]);
}
}
7.归并排序(喝前摇一摇,考前看一看)
void func(int A[], int low, int mid, int high){
int *B = new int[high-low+1];
int i = low;
int j = mid+1;
int k;
for(k=low; k<=high; k++){
B[k] = A[k];
}
for(k = i; i<=mid&&j<=high; k++){
if(B[i] <= B[j]){
A[k] = B[i++];
}else{
A[k] = B[j++];
}
}
while(j <= high){
A[k++] = B[j++];
}
while(i <= mid){
A[k++] = B[i++];
}
}
void mergeSort(int A[], int low, int high){
if(low < high){
int mid = (low+high)/2;
mergeSort(A, low, mid);
mergeSort(A, mid+1, high);
func(A, low, mid, high);
}
}
八、408近3年真题
已知无向连通图G由顶点集V和边集E组成,|E|>0,当G中度为奇数的顶点个数为不大于2的偶数时,G存在包含所有边且长度为|E|的路径(称为EL路径),设图G采用邻接矩阵存储,类型定义如下:
typedef struct{
int numVertices, numEdges;
char VerticesList[MAXV];
int Edge[MAXV][MAXV];
}MGraph;
请设计算法 int isExistEL(MGraph G),判断G是否存在EL路径,若存在,则返回1,否则返回0.要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
(3)说明你所设计算法的时间复杂度和空间复杂度。
int isExistEL(MGraph G){
int degree;
int count = 0;
for(int i=0; i<G.numVertices; i++){
degree = 0;
for(int j=0; j<G.numVertives; j++){
if(G.Edge[i][j] != 0){
degree++;
}
}
if(degree%2 != 0){
count++;
}
}
if(count==0 || count==2){
return 1;
}else{
return 0;
}
}
void cmpCountSort(int a[], int b[], int n){
int i, j, *count;
count = (int *)malloc(sizeof(int) * n);
for(i=0; i<n-1; i++){
count[i] = 0;
}
for(i=0; i<n-1; i++){
for(j=i+1; j<n; j++){
if(a[i] < a{j}){
count[j]++;
}else{
count[i]++;
}
}
}
for(i=0; i<n; i++){
b[count[i]] = a[i];
}
free(count);
}
顺序存储下判断二叉树是否为二叉排序树,若是,则返回ture,否则,返回false。
结构体
typedef struct{
int SqBiTNode[MAX_SIZE];
int ElemNum;
}SqBiTree;
T中不存在的结点在数组中用SqBiTNode中用-1表示。
对于有向图,如果一个顶点的出度大于入度,则这个顶点称为K顶点。有向图用邻接矩阵存储,数据结构定义如下:
typedef struct{
int numVertex, numEdge;
char VertexList[MAXV];
int Edge[MAXV][MAXV];
}MGraph;
要求实现函数int printVertices(MGraph G),输出有向图中所有K顶点,并返回K顶点的总数。
(1)说明算法思想。
(2)用C/C++实现算法。
int printVertices(MGraph G){
int out[G.numVertex];
int in[G.numvertex];
for(int i=0; i<G.numVertex; i++){
for(int j=0; j<G.numvertex; j++){
if(G.Edge[i][j] != 0){
out[i]++;
}
if(G.Edge[j][i] != 0){
in[j]++;
}
}
}
for(int i=0; i<G.numvertex; i++){
if(out[i] > in[i]){
count++;
cout << VertexList[i];
}
}
return count;
}