数据结构yyds

## 实验1
### 8576 顺序线性表的基本操作
```cpp
#include<stdio.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

typedef struct
{
    int *elem;
    int length;
    int listsize;
}SqList;

int InitList_Sq(SqList &L)
{
// 算法2.3,构造一个空的线性表L,该线性表预定义大小为LIST_INIT_SIZE
// 请补全代码
    L.elem = (int*)malloc(LIST_INIT_SIZE*sizeof(int));
    if(!L.elem) return ERROR;
    L.length = 0;
    L.listsize = LIST_INIT_SIZE;
    return OK;
}

int Load_Sq(SqList &L)
{
// 输出顺序表中的所有元素
    int i;
    if(!L.length) printf("The List is empty!");  // 请填空
    else
    {
        printf("The List is: ");
        for(int i=0;i<L.length;i++) printf("%d ",L.elem[i]);  // 请填空
    }
    printf("\n");
    return OK;
}

int ListInsert_Sq(SqList &L,int i,int e)
{
// 算法2.4,在顺序线性表L中第i个位置之前插入新的元素e
// i的合法值为1≤i≤L.length +1
// 请补全代码
    if(i<1 || i>L.length+1) return ERROR;
    if(L.length+1>LIST_INIT_SIZE){
        int* newbase = (int*)realloc(L.elem,sizeof(int)*(L.listsize+LISTINCREMENT));//用于判断是否能分配成功
        if(!newbase) return ERROR;;
        L.elem = newbase;
        L.listsize += LISTINCREMENT;
    }
    int *q = &(L.elem[i-1]);
    for(int *p = &(L.elem[L.length-1]);p>=q;p--){
        *(p+1) = *p;
    }
    ++L.length;
    *q = e;
    return OK;
}

int ListDelete_Sq(SqList &L,int i, int &e)
{
// 算法2.5,在顺序线性表L中删除第i个位置的元素,并用e返回其值
// i的合法值为1≤i≤L.length
// 请补全代码
    if(i<1 || i>L.length){
        return ERROR;
    }
    int *q = &(L.elem[i-1]);
    e = *q;
    for(int* p = &(L.elem[L.length-1]);q<p;q++){
        *(q) = *(q+1);
    }
    --L.length;
    return e;
}

int main()
{
    SqList T;
    int a, i;
    ElemType e, x;
    if(InitList_Sq(T))    // 判断顺序表是否创建成功
    {
        printf("A Sequence List Has Created.\n");
    }
    while(1)
    {
        printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
        scanf("%d",&a);
        switch(a)
        {
            case 1: scanf("%d%d",&i,&x);
                if(!ListInsert_Sq(T,i,x)) printf("Insert Error!\n"); // 执行插入函数,根据返回值判断i值是否合法
                else printf("The Element %d is Successfully Inserted!\n", x);
                break;
            case 2: scanf("%d",&i);
                if(!ListDelete_Sq(T,i,e)) printf("Delete Error!\n"); // 执行删除函数,根据返回值判断i值是否合法
                else printf("The Element %d is Successfully Deleted!\n", e);
                break;
            case 3: Load_Sq(T);
                break;
            case 0: return 1;
        }
    }
}
```
###  8579 链式线性表的基本操作
```cpp
#include<stdio.h>
#include<malloc.h>
#define ERROR 0
#define OK 1
#define ElemType int

typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode,*LinkList;

int CreateLink_L(LinkList &L,int n){
// 创建含有n个元素的单链表
    LinkList p,q;
    int i;
    ElemType e;
    L = new LNode;
    L->next = NULL;              // 先建立一个带头结点的单链表
    q = L;
    for (i=0; i<n; i++) {
        scanf("%d", &e);
        p = new LNode;  // 生成新结点
        p->data = e;
        q->next = p;
        q = p;
    }
    return OK;
}

int LoadLink_L(LinkList &L){
// 单链表遍历
    LinkList p = L->next;
    if(p==NULL)printf("The List is empty!"); // 请填空
    else
    {
        printf("The LinkList is:");
        while(p!=NULL)    // 请填空
        {
            printf("%d ",p->data);
            p = p->next;
        }
    }
    printf("\n");
    return OK;
}

int LinkInsert_L(LinkList &L,int i,ElemType e){
// 算法2.9
// 在带头结点的单链线性表L中第i个位置之前插入元素e
    LinkList p = L;
    int j = 0;
    while(p!=NULL && j<i-1){
        p = p->next;
        j++;
    }
    if(p==NULL || j>i-1) return ERROR;
    LinkList s = new LNode;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}

int LinkDelete_L(LinkList &L,int i, ElemType &e){
// 算法2.10
// 在带头结点的单链线性表L中,删除第i个元素,并用e返回其值
    LinkList p = L;
    int j = 0;
    while(p->next!=NULL && j<i-1){
        p = p->next;
        j++;
    }
    if(p->next==NULL || j>i-1) return ERROR;
    LinkList q = p->next;
    e = q->data;
    p->next = q->next;
    delete q;
    return OK;
}
int main()
{
    LinkList T;
    int a,n,i;
    ElemType x, e;
    printf("Please input the init size of the linklist:\n");
    scanf("%d",&n);
    printf("Please input the %d element of the linklist:\n", n);
    if(CreateLink_L(T,n))
    {
        printf("A Link List Has Created.\n");
        LoadLink_L(T);
    }
    while(1)
    {
        printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
        scanf("%d",&a);
        switch(a)
        {
            case 1: scanf("%d%d",&i,&x);
                if(LinkInsert_L(T,i,x)) printf("The Element %d is Successfully Inserted!\n", x);
                else printf("Insert Error!\n");
                break;
            case 2: scanf("%d",&i);
                if(LinkDelete_L(T,i,e)) printf("The Element %d is Successfully Deleted!\n", e);
                else printf("Delete Error!\n");
                break;
            case 3: LoadLink_L(T);
                break;
            case 0: return 1;
        }
    }
}
```
### 8580 合并链表
```cpp
#include<stdio.h>
#include<malloc.h>
#define ERROR 0
#define OK 1 
#define ElemType int

typedef int Status;
typedef struct LNode
{
 int data;
 struct LNode *next;
}LNode,*LinkList;

Status InitList_L(LinkList &L) {
  // 操作结果:构造一个空的线性表L
  L = (LinkList)malloc(sizeof(LNode));  // 产生头结点
  if (!L) return ERROR;                 // 存储分配失败
  L->next = NULL;                       // 指针域为空
  return OK;
} // InitList_L


void PrintList_L(LinkList L) {
  // 输出单链线性表L的所有元素值
  LinkList p = L->next;
  while (p) {
    printf("%d ", p->data);
    p = p->next;
  }
  printf("\n");
} // PrintList_L

Status ListInsert_L(LinkList &L, int i, ElemType e) {  // 算法2.9
  // 在带头结点的单链线性表L的第i个元素之前插入元素e
  LinkList p,s;
  p = L;   
  int j = 0;
  while (p && j < i-1) {  // 寻找第i-1个结点
    p = p->next;
    ++j;
  } 
  if (!p || j > i-1) return ERROR;      // i小于1或者大于表长
  s = (LinkList)malloc(sizeof(LNode));  // 生成新结点
  s->data = e;  s->next = p->next;      // 插入L中
  p->next = s;
  return OK;
} // LinstInsert_L

Status ListDelete_L(LinkList &L, int i, ElemType &e) {  // 算法2.10
  // 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
  LinkList p,q;
  p = L;
  int j = 0;
  while (p->next && j < i-1) {  // 寻找第i个结点,并令p指向其前趋
    p = p->next;
    ++j;
  }
  if (!(p->next) || j > i-1) return ERROR;  // 删除位置不合理
  q = p->next;
  p->next = q->next;           // 删除并释放结点
  e = q->data;
  free(q);
  return OK;
} // ListDelete_L
void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) {
  // 已知单链线性表La和Lb的元素按值非递减排列。
  // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。
  LinkList pa = La->next, pb = Lb->next, pc;
  Lc = pc = La;           // 用La的头结点作为Lc的头结点
  while (pa && pb) {
    if (pa->data <= pb->data) {
      pc->next = pa;
      pc = pa;
      pa = pa->next;
    } else {
      pc->next = pb;
      pc = pb;
      pb = pb->next;
    }
  }
  pc->next = pa ? pa : pb;  // 插入剩余段
  free(Lb);                 // 释放Lb的头结点
} // MergeList_L

int main() {
  LinkList La, Lb, Lc;
  int m, n;
  scanf("%d", &m);
  InitList_L(La);
  for (int i = 1; i <= m; ++i) {
    int x;
    scanf("%d", &x);
    ListInsert_L(La, i, x);
  }
  scanf("%d", &n);
  InitList_L(Lb);
  for (int i = 1; i <= n; ++i) {
    int x;
    scanf("%d", &x);
    ListInsert_L(Lb, i, x);
  }
  printf("List A:");
  PrintList_L(La);
  printf("List B:");
  PrintList_L(Lb);
  MergeList_L(La, Lb, Lc);
  printf("List C:");
  PrintList_L(Lc);
  return 0;
} // main
```
### 19080 反转链表
```cpp
nex  = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
```
## 实验2
### 8583 顺序栈的基本操作
```cpp
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量

typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等

struct SqStack
{
     SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
     SElemType *top; // 栈顶指针
     int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈

Status InitStack(SqStack &S)
{
     S.base = new int[STACK_INIT_SIZE];
     S.top = S.base;
     S.stacksize = STACK_INIT_SIZE;
     return OK;

}

Status Push(SqStack &S,SElemType e)
{
        if(S.top - S.base == S.stacksize){
            return ERROR;
        }//斩满,无法进栈
        else{
            *S.top = e;
            S.top++;
        }
        return OK;
}

Status Pop(SqStack &S,SElemType &e)
{
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
// 请补全代码
       if(S.top == S.base){
            return ERROR;
       }
       S.top--;
       e = *S.top;
       return OK;

}

Status GetTop(SqStack S,SElemType &e)
{
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
// 请补全代码

        if(S.top == S.base){
            return ERROR;
        }else{
            e = *(--S.top);
        }
        return OK;
}

int StackLength(SqStack S)
{
// 返回栈S的元素个数
// 请补全代码
        if(S.top == S.base){
            return 0;
        }else{
            return S.top- S.base;
        }

}

Status StackTraverse(SqStack S)
{
// 从栈顶到栈底依次输出栈中的每个元素
	SElemType *p  =  S.top ; //请填空
	if(S.top == S.base)printf("The Stack is Empty!"); //请填空
	else
	{
		printf("The Stack is: ");
		while(p--)            //请填空
		{
		    if(p==S.base){
                printf("%d ", *p);
                break;
		    }
                         //请填空
			printf("%d ", *p);

		}
	}
	printf("\n");
	return OK;
}

int main()
{
     int a;
     SqStack S;
SElemType x, e;
     if(InitStack(S))    // 判断顺序表是否创建成功,请填空
{
	printf("A Stack Has Created.\n");
}
while(1)
	{
    printf("1:Push \n2:Pop \n3:Get the Top \n4:Return the Length of the Stack\n5:Load the Stack\n0:Exit\nPlease choose:\n");
	scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d", &x);
		      if(!Push(S,x)) printf("Push Error!\n"); // 判断Push是否合法,请填空
		      else printf("The Element %d is Successfully Pushed!\n", x);
		      break;
		case 2: if(!Pop(S,e)) printf("Pop Error!\n"); // 判断Pop是否合法,请填空
			  else printf("The Element %d is Successfully Poped!\n", e);
		  	  break;
		case 3: if(!GetTop(S,e))printf("Get Top Error!\n"); // 判断Get Top是否合法,请填空
			  else printf("The Top Element is %d!\n", e);
		   	  break;
			case 4: printf("The Length of the Stack is %d!\n",S.top - S.base); //请填空
				  break;
			case 5:
                    StackTraverse(S);//请填空
				  break;
			case 0: return 1;
		}
	}
}
```
### 8584 循环队列的基本操作
```cpp
#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int QElemType;
#define MAXQSIZE 100 // 最大队列长度(对于循环队列,最大队列长度要减1)

typedef struct
{
   QElemType *base; // 初始化的动态分配存储空间
   int front; // 头指针,若队列不空,指向队列头元素
   int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
 }SqQueue;

Status InitQueue(SqQueue &Q)
{
// 构造一个空队列Q,该队列预定义大小为MAXQSIZE
// 请补全代码
	Q.base = new int[MAXQSIZE];
	if(Q.base == NULL){
        return ERROR;
	}
	Q.front =Q.rear =0;
	return true;
}

Status EnQueue(SqQueue &Q,QElemType e)
{
// 插入元素e为Q的新的队尾元素
// 请补全代码
    if((Q.rear+1)%MAXQSIZE!= Q.front){
            Q.base[Q.rear] = e;
            Q.rear = (Q.rear+1)%MAXQSIZE;
            return OK;
    }else{
            return ERROR;
    }


}

Status DeQueue(SqQueue &Q, QElemType &e)
{
// 若队列不空, 则删除Q的队头元素, 用e返回其值, 并返回OK; 否则返回ERROR
// 请补全代码
	if(Q.front == Q.rear){
        return ERROR;
	}else{
        e = Q.base[Q.front] ;
        Q.front = (Q.front + 1)%MAXQSIZE;
        return OK;
	}

}

Status GetHead(SqQueue Q, QElemType &e)
{
// 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR
// 请补全代码
    if(Q.front == Q.rear){
        return false;
    }else{
        e = Q.base[Q.front];
        return OK;
    }


}

int QueueLength(SqQueue Q)
{
// 返回Q的元素个数
// 请补全代码
    return (Q.rear - Q.front +MAXQSIZE)%MAXQSIZE;

}

Status QueueTraverse(SqQueue Q)
{
// 若队列不空,则从队头到队尾依次输出各个队列元素,并返回OK;否则返回ERROR.
	int i;
	i=Q.front;
	if(Q.front == Q.rear){
            printf("The Queue is Empty!");
            return ERROR;
	}else{
		printf("The Queue is: ");
		while(i!=Q.rear)     //请填空
		{
			printf("%d ",Q.base[i] );   //请填空
			i = i+1;   //请填空
		}
	}
	printf("\n");
	return OK;
}

int main()
{
	int a;
    SqQueue S;
	QElemType x, e;
  if(InitQueue(S))    // 判断顺序表是否创建成功,请填空
	{
		printf("A Queue Has Created.\n");
	}
	while(1)
	{
	printf("1:Enter \n2:Delete \n3:Get the Front \n4:Return the Length of the Queue\n5:Load the Queue\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d", &x);
				  if(!EnQueue(S,x)) printf("Enter Error!\n"); // 判断入队是否合法,请填空
				  else printf("The Element %d is Successfully Entered!\n", x);
				  break;
			case 2: if(!DeQueue(S,e)) printf("Delete Error!\n"); // 判断出队是否合法,请填空
				  else printf("The Element %d is Successfully Deleted!\n", e);
				  break;
			case 3: if(!GetHead(S,e))printf("Get Head Error!\n"); // 判断Get Head是否合法,请填空
				  else printf("The Head of the Queue is %d!\n", e);
				  break;
			case 4: printf("The Length of the Queue is %d!\n",QueueLength(S));  //请填空
				  break;
			case 5: QueueTraverse(S); //请填空
				  break;
			case 0: return 1;
		}
	}
}
```
### 8585 栈的应用——进制转换
```cpp
#include<iostream>
#include<stack>
using namespace std;
int main(){
    stack<int> s;
    int n;
    cin>>n;
    if(n==0) s.push(0);
    while(n){
        s.push(n%8);
        n/=8;
    }
    while(!s.empty()){
        cout<<s.top();
        s.pop();
    }
    return 0;
}
```
### 8586 括号匹配检验
```cpp
typedef char SElemType;
#include"malloc.h"
#include"stdio.h"
#include"math.h"
#include"stdlib.h" // exit()
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 // 存储空间分配增量
struct SqStack
{
 SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
 SElemType *top; // 栈顶指针
 int stacksize; // 当前已分配的存储空间,以元素为单位
 }; // 顺序栈
Status InitStack(SqStack &S)
{
    S.base = new char[STACK_INIT_SIZE];
    if(!S.base) return ERROR;
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
 }

Status StackEmpty(SqStack S)
{
    if(S.top == S.base)
        return TRUE;
    return  FALSE;

 }
Status Push(SqStack &S,SElemType e)
{
    if(S.top -S.base ==S.stacksize) return ERROR;
    *S.top = e;
    S.top++;
    return OK;

 }
 Status Pop(SqStack &S,SElemType &e)

{
    if(S.top == S.base) return ERROR;
    S.top--;
    e = *S.top;
    return OK;
 }
void check()
 { // 对于输入的任意一个字符串,检验括号是否配对
   SqStack s;
   SElemType ch[80],*p,e;
   if(InitStack(s)) // 初始化栈成功
   {
    //printf("请输入表达式\n");
     scanf("%s",ch);
     p=ch;
     while(*p) // 没到串尾
       switch(*p)
       {
         case '(':
         case '[':Push(s ,*p++);
                  break; // 左括号入栈,且p++
         case ')':
         case ']':if(!StackEmpty(s)) // 栈不空
                  {
                    Pop(s,e); // 弹出栈顶元素
                    if(((*p==')')&&(e!='('))||((*p==']')&&(e!='[')))
                                                // 弹出的栈顶元素与*p不配对
                    {
                      printf("isn't matched pairs\n");
                      exit(0);
                    }
                    else
                    {
                      p++;
                      break; // 跳出switch语句
                    }
                  }
                  else // 栈空
                  {
                    printf("lack of left parenthesis\n");
                    exit(ERROR);
                  }
         default:   p++; // 其它字符不处理,指针向后移
       }
     if(StackEmpty(s)) // 字符串结束时栈空
       printf("matching\n");
     else
       printf("lack of right parenthesis\n");
   }
 }
int main()
 {
   check();
 }
```
### 8587 行编辑程序
```cpp
#include<string>//行编辑程序
#include<stack>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
 
const int N = 10005;
 
int main()
{
	char ch;
	int n;
	cin >> n;
	ch = getchar();//读入第一个字符,换行符
	for (int i = 1; i <= n; i++)
	{
		vector<char>s;//使用vecotor模板,可当作栈
		ch = getchar();
		while (ch != '\n')
		{
			switch (ch)
			{
			case '#':
				if (!s.empty())
				{
					s.pop_back();
				}
				break; //末尾字符退栈
			case '@':
				s.clear();
     			break; //清空栈
			default:
				s.push_back(ch); //有效字符进栈
			}
			ch = getchar(); //接收下一个字符
		}
		for (int i = 0; i < s.size(); i++)//输出
		{
			cout << s[i];
		}
		cout << endl;
	}
	return 0;
}


typedef char SElemType;
#include"malloc.h"
#include"stdio.h"
#include"math.h"
#include"stdlib.h" // exit()
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
 #define STACKINCREMENT 2 // 存储空间分配增量
struct SqStack
{
 SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
 SElemType *top; // 栈顶指针
 int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈

Status InitStack(SqStack &S)
{ // 构造一个空栈S
  S.base = S.top = new SElemType[STACK_INIT_SIZE];
  if(!S.base) return ERROR;
  S.stacksize = STACK_INIT_SIZE;
  return OK;
 }
Status StackEmpty(SqStack S)
 { // 若栈S为空栈,则返回TRUE,否则返回FALSE
   if(S.base == S.top) return TRUE;
   return FALSE;
 }
Status ClearStack(SqStack &S)
 { // 把S置为空栈
   S.top=S.base;
   return OK;
 }
Status DestroyStack(SqStack &S)
 { // 销毁栈S,S不再存在
   free(S.base);
   S.base=NULL;
   S.top=NULL;
   S.stacksize=0;
   return OK;
 }
Status Push(SqStack &S,SElemType e)
 { // 插入元素e为新的栈顶元素
   *S.top = e;
   S.top++;
   return OK;
 }
 Status Pop(SqStack &S,SElemType &e)
 { // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
   if(S.top == S.base) return ERROR;
   S.top--;
   e = *S.top;
   return OK;
 }
Status StackTraverse(SqStack S,Status(*visit)(SElemType))
 { // 从栈底到栈顶依次对栈中每个元素调用函数visit()。
   // 一旦visit()失败,则操作失败
   while(S.top>S.base)
     visit(*S.base++);
   printf("\n");
   return OK;
 }
Status visit(SElemType c)
 {
   printf("%c",c);
   return OK;
 }
 void LineEdit()
 { // 利用字符栈s,从终端接收一行并送至调用过程的数据区。算法3.2
   SqStack s;
   char ch,c;
   int n,i;
   InitStack(s);
   scanf("%d",&n);
   ch=getchar();
   for(i=1;i<=n;i++)
   { ch=getchar();
     while(ch!='\n')
    {
       switch(ch)
       {
         case '#':Pop(s,c);
                  break; // 仅当栈非空时退栈
         case '@':ClearStack(s);
                  break; // 重置s为空栈
         default :Push(s,ch); // 有效字符进栈
       }
       ch = getchar(); // 从终端接收下一个字符
     }
     StackTraverse(s,visit); // 将从栈底到栈顶的栈内字符输出
     ClearStack(s); // 重置s为空栈
    }
   DestroyStack(s);
 }
 int main()
 {
     LineEdit();
     return 0;
 }
```
### 8588 表达式求值
```cpp
#include<cstdlib>
#include<cstdio>
#include <iostream>
#include <cstring>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量

typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
using namespace  std;
struct SqStack
{
    SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
    SElemType *top; // 栈顶指针
    int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈

Status InitStack(SqStack &S)
{
// 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE
    S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    if(!S.base) return ERROR;
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    return OK;
}

Status Push(SqStack &S,SElemType e)
{
// 在栈S中插入元素e为新的栈顶元素
    if(S.top-S.base>=S.stacksize)
    {
        S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
        if(!S.base) return ERROR;
        S.top=S.base+S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    *S.top++=e;
    return OK;
}

Status Pop(SqStack &S,SElemType &e)
{
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
    if(S.top==S.base) return ERROR;
    e=*--S.top;
    return OK;
}

Status GetTop(SqStack S,SElemType &e)
{
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
    if(S.top==S.base) return ERROR;
    e=*(S.top-1);
    return OK;
}

int StackLength(SqStack S)
{
// 返回栈S的元素个数
    int i;
    i=S.top-S.base;
    return i;
}

Status StackTraverse(SqStack S)
{
// 从栈顶到栈底依次输出栈中的每个元素
    SElemType *p = (SElemType *)malloc(sizeof(SElemType));
    p = S.top;
    if(S.top==S.base)printf("The Stack is Empty!");
    else
    {
        printf("The Stack is: ");
        p--;
        while(p>=S.base)
        {
            printf("%d ", *p);
            p--;
        }
    }
    printf("\n");
    return OK;
}

char prio(char e,char c){//比较运算符优先级
    char n;
    switch(c){
        case'+':
        case'-':{
            if(e=='('||e=='=') n='<';  //c>e
            else n='>';}break;
        case'*':
        case'/':{
            if(e=='*'||e=='/'||e==')') n='>';//c<e
            else n='<';}break;
        case'(':{
            if(e==')')
            {
                printf("括号不匹配\n");
                exit(ERROR);
            }
            else n='<';} //c>e;
            break;
        case')':{
            if(e=='(') n='=';
            else if(e=='=') {printf("缺少左括号\n");exit(ERROR);}
            else n='>';
        }//e>c
            break;
        case'=':{
            if(e=='=') n='=';
            else if(e=='(') {printf("缺少右括号\n");exit(ERROR);}
            else n='>';
        } //e>c
    }//switch

    return n;
}

int main()
{
    SqStack s1,s2;//s1操作数栈,s2算符栈
    InitStack(s1);
    InitStack(s2);
    Push(s2,'=');
    char w;
    w=getchar();
        int e;
        GetTop(s2,e);
        while(w!='='||e!='=')
        {
          //  cout<<w<<endl;
          int d=0;
          if(w>='0'&&w<='9') {
              while (w >= '0' && w <= '9') {
                  d = d * 10 + (w - '0');
                  w = getchar();
              }
              Push(s1, d);
             // cout << d << endl;
          }
          else {
              if (prio(e, w) == '<') {
                  //cout<<"123"<<endl;
                  Push(s2, w);
                  //StackTraverse(s1);
                  w = getchar();

              } else if (prio(e, w) == '=' && w == ')') {
                  //cout<<"321"<<endl;
                  int t;
                  Pop(s2, t);
                  w = getchar();
              } else if (prio(e, w) == '>') {
                  int a, b, c = 0, d;
                  Pop(s1, a);
                  Pop(s1, b);
                  Pop(s2, d);
                  if (d == '+')
                      c = a + b;
                  else if (d == '-')
                      c = b - a;
                  else if (d == '/')
                      c = b / a;
                  else if (d == '*')
                      c = b * a;
                  Push(s1, c);
              }
          }
            GetTop(s2,e);
        }
        int r;
        Pop(s1,r);
        cout<<r<<endl;
    return 0;
}
```
### 18938 汉诺塔问题
```cpp
#include <iostream>
#include <algorithm>
#include <set>
#include <cmath>
#include <cstring>
#include <map>

using namespace std;

int num;
char a,b,c;

void move(int n,char a,char b){
    printf("%c->%d->%c\n", a, n, b);
}

void hanoi(int n,char a,char b,char c){
    if(n == 1) {
        printf("%c->%d->%c\n", a, n ,c);
        return;
    }else{
        hanoi(n-1,a,c,b);
        move(n,a,c);
        hanoi(n-1,b,a,c);
    }
}

int main(){
    cin>>num;
    cin>>a>>b>>c;
    hanoi(num,a,c,b);
    return 0;
}
```
### 8590 队列的应用——银行客户平均等待时间
```cpp
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 10000;
int T,timing,k;
int a[N][N];
double average,sum;

int main(){
    cin>>T;
    cin>>a[k][0]>>a[k][1];
    timing = a[k][0]+a[k++][1];
    T--;
    while(T--){
        cin>>a[k][0]>>a[k][1];
        if(a[k][0] <= timing){
            sum += timing - a[k][0];
            timing += a[k][1];
        }else{
            timing = (a[k][0]+a[k][1]);
        }
        k++;
    }
    average = sum/(k);
    printf("%.2f",average);
    return 0;
}
```
### 18937 阿克曼(Ackmann)函数
```cpp
#include <iostream>
#include <algorithm>

using namespace std;


int akm(int a,int b){
    if(!a) {
        return b+1;
    }else if((!b)&&a>0){
        return akm(a-1,1);
    }else if(a>0&&b>0) {
        return akm(a-1,akm(a,b-1));
    }        
}

int main(){
    int a,b;
    cin>>a>>b;
    cout<<akm(a,b)<<endl;
    return 0;
}
```
## 实验3
### 8591 计算next值
```cpp
#include "stdio.h"
#include "stdlib.h"
#include "iostream"
#define  MAXSTRLEN  255                   // 用户可在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN+1];	// 0号单元存放串的长度

void get_next(SString T,int next[]){
// 算法4.7
// 求模式串T的next函数值并存入数组next
   // 请补全代码
    int i=1,j=0;next[1]=0;
    while(i<=T[0]) {
        if(j==0||T[i]==T[j]) {next[++i]=++j;}
        else j=next[j];
    }
}

int main(){
int next[MAXSTRLEN];
SString S;
int n,i,j;
char ch;
scanf("%d",&n);    // 指定要验证NEXT值的字符串个数
ch=getchar();
for(i=1;i<=n;i++)    
{
ch=getchar();
for(j=1;j<=MAXSTRLEN&&(ch!='\n');j++)    // 录入字符串
{
S[j]=ch;
ch=getchar();
}
S[0]=j-1;    // S[0]用于存储字符串中字符个数
get_next(S,next);
printf("NEXT J is:");
for(j=1;j<=S[0];j++)
printf("%d",next[j]);
printf("\n");
}
return 0;
}
```
### 8592 KMP算法
```cpp
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define TRUE  1
#define FALSE  0
#define OK  1
#define ERROR  0
#define INFEASLBLE  -1
#define OVERFLOW  -2
#define MAXSTRLEN  255 	//用户可在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN+1];	//0号单元存放串的长度

void get_next(SString T,int next[]){
// 算法4.7
// 求模式串T的next函数值并存入数组next
   // 请补全代码
	next[1] = 0;
	int i=1,j=0;
	while(i < T[0]){
		if(j==0 || T[i]==T[j]){
			i++;
			j++;
			next[i] = j;
		}else{
			j = next[j];
		}
	}
}

int Index_KMP(SString S,SString T,int pos){
// 算法4.6
// 利用模式串T的next函数求T在主串S中第pos个字符之后的位置
// KMP算法。请补全代码
	int next[MAXSTRLEN+1],i=0,j=0;
	get_next(T,next);
	while(i<=S[0]&&j<=T[0]){
		if(j==0 || S[i]==T[j]){
			i++;
			j++;
		}else{
			j = next[j];
		}
	}
	if(j>=T[0])
		return i-T[0];
	else
		return 0;
}
int main()
{
SString T,S;
 int i,j,n;
 char ch;
 int pos;
 scanf(" %d", &n);    // 指定n对需进行模式匹配的字符串
ch=getchar();
for(j=1;j<=n;j++)
{
ch=getchar();
  for( i=1;i<=MAXSTRLEN&&(ch!='\n');i++)    // 录入主串
  {
S[i]=ch;
  ch=getchar();
}
S[0]=i-1;    // S[0]用于存储主串中字符个数
ch=getchar();
for( i=1;i<=MAXSTRLEN&&(ch!='\n');i++)    // 录入模式串
{
  T[i]=ch;
  ch=getchar();
}
T[0]=i-1;    // T[0]用于存储模式串中字符个数
pos=Index_KMP(S,T,0);    // 请填空
printf("%d\n",pos);
}
return 0;
}
```
### 18722 稀疏矩阵的运算
```cpp
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;
const int N=1E7;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0);
struct point{
    int row;
    int col;
    int val;
    point(){row=2,col=0,val=0;}
};
vector<point> a(N);

bool cmp(point a,point b){
    if(a.row != b.row){
        return a.row<b.row;
    }
    else return a.col<b.col;
}
int main(){
    IOS;
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=0;i<k;i++){
        cin>>a[i].row>>a[i].col>>a[i].val;
        swap(a[i].row,a[i].col);
    }
    sort(a.begin(),a.begin()+k,cmp);
    for(int i=0;i<k;i++){
        cout<<a[i].row<<' ';
        cout<<a[i].col<<' ';
        cout<<a[i].val;
        cout<<endl;
    }
    return 0;
}
```
### 18769 不完整的排序
```cpp
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;
const int N=1E5;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0);

int main(){
    IOS;
    int T,n,a[N];
    cin>>T;
    while(T--){
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        int i=0,j=n-1;
        while(i<j){
            while(a[i]<0&&i<j) i++;
            while(a[j]>0&&j>i) j--;
            swap(a[i],a[j]);
        }
        for(int i=0;i<n;i++){
            cout<<a[i]<<' ';
        }
        cout<<endl;
    }
    return 0;
}
```
## 实验4
### 8606 二叉树的构建及遍历操作
```cpp
#include "stdio.h"
#include "malloc.h"
#define TRUE 1
#define FALSE 0
#define OK  1
#define ERROR  0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int  Status;

typedef char  ElemType;
typedef struct BiTNode{
  ElemType data;
  struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;

Status CreateBiTree(BiTree &T) {  // 算法6.4
  // 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,
  // 构造二叉链表表示的二叉树T。
  char ch;
  scanf("%c",&ch);
  if (ch=='#') T = NULL;
  else {
    if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
    T->data = ch; // 生成根结点
    CreateBiTree(T->lchild);// 构造左子树
    CreateBiTree(T->rchild); // 构造右子树
  }
  return OK;
} // CreateBiTree



Status PreOrderTraverse( BiTree T) {
    if(T){
        printf("%c",T->data);// 前序遍历二叉树T的递归算法
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);//补全代码,可用多个语句
    }
    return OK;
} // PreOrderTraverse

Status InOrderTraverse( BiTree T) {
    if(T){
        InOrderTraverse(T->lchild);
        printf("%c",T->data);// 中序遍历二叉树T的递归算法
        InOrderTraverse(T->rchild);//补全代码,可用多个语句
    }
    return OK;
} // InOrderTraverse

Status PostOrderTraverse( BiTree T) {
    if(T){
        PostOrderTraverse(T->lchild);// 后序遍历二叉树T的递归算法
        PostOrderTraverse(T->rchild);//补全代码,可用多个语句
        printf("%c",T->data);
    }
    return OK;
} // PostOrderTraverse



int main()   //主函数
{
    BiTree T;
    CreateBiTree(T);
    PreOrderTraverse(T);
    printf("\n");
    InOrderTraverse(T);
    printf("\n");
    PostOrderTraverse(T);
    return 0;//补充代码
 }//main
```
### 17121 求二叉树各种节点数
```cpp
#include "stdio.h"
#include "malloc.h"
#define TRUE 1
#define FALSE 0
#define OK  1
#define ERROR  0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int  Status;
int x1,x2,x3;
typedef char  ElemType;
typedef struct BiTNode{
    ElemType data;
    struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;

Status CreateBiTree(BiTree &T) {  // 算法6.4
    // 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,
    // 构造二叉链表表示的二叉树T。
    char ch;
    scanf("%c",&ch);
    if (ch=='#') T = NULL;
    else {
        if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
        T->data = ch; // 生成根结点
        CreateBiTree(T->lchild);   // 构造左子树
        CreateBiTree(T->rchild);  // 构造右子树
    }
    return OK;
} // CreateBiTree

void PreOrdertree(BiTree &T){
    if(T){
        if((!(T->lchild==NULL)) + (!(T->rchild == NULL)) == 2){
            x1++;
        }else if((!(T->lchild==NULL)) + (!(T->rchild == NULL)) == 1){
            x2++;
        }else{
            x3++;
        }
        PreOrdertree(T->lchild);
        PreOrdertree(T->rchild);
    }
}
int main()   //主函数
{
    BiTree T;
    CreateBiTree(T);
    PreOrdertree(T);
    printf("%d\n",x1);
    printf("%d\n",x2);
    printf("%d\n",x3);
    return 0;
}//main
```
### 18924 二叉树的宽度
```cpp
#include "stdio.h"
#include "malloc.h"
int level[60];
struct TreeNode{
    int p;
    int lchild;
    int rchild;
};

TreeNode tree[60];

void Creatbittree(int p,int c){
    tree[c].p = p;
    if(!tree[p].lchild){
        tree[p].lchild = c;
    }else{
        tree[p].rchild = c;
    }
}

void kuandu(int root,int val){
    level[val]++;
    if(tree[root].lchild){
        kuandu(tree[root].lchild,val+1);
    }
    if(tree[root].rchild){
        kuandu(tree[root].rchild,val+1);
    }
}
int main()   //主函数
{
    int T,tmp1,tmp2,root,ans=0;
    scanf("%d",&T);
    for(int i=1;i<T;i++){
        scanf("%d %d",&tmp1,&tmp2);
        Creatbittree(tmp1,tmp2);
    }
    for(int i=1;i<=T;i++){
        if(tree[i].p==0){
            root = i;
            break;
        }
    }
    kuandu(root,1);
    for(int i=1;i<60;i++){
        if(level[i]>=ans){
            ans = level[i];
        }
    }
    printf("%d",ans);
    return 0;
}//main
```

```cpp
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

typedef struct tree{
	int lchild=0;
	int rchild=0;
}tree;

int main()   //主函数
{
	int n;
	int x,y;
	tree T[150];
	cin>>n;
	for(int i=1;i<n;i++){
		cin>>x>>y;
		if(!T[x].lchild) T[x].lchild=y;
		else T[x].rchild=y;
	}
	int ans=1;//初始化为最小值
	queue<int> q;
	q.push(1);
	while(q.size()){
		int len=q.size();
		ans = max(ans,len);
		for(int i=1;i<=len;i++){
			int t=q.front();
			q.pop();
			if(T[t].lchild) q.push(T[t].lchild);
			if(T[t].rchild) q.push(T[t].rchild);//这里并不是二选一,而是有就选 
		}
	}
	cout<<ans<<endl;
	return 0;
 }//main

```

### 18724 二叉树的遍历运算
```cpp
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
 
using namespace std;
 
void Traverse(string pre,string in)
{
    if(pre=="\0" || in=="\0")
        return;
    int pos=in.find(pre[0]);//根据先序找到根结点在中序的位置
    Traverse(pre.substr(1,pos),in.substr(0,pos));//左子树
    Traverse(pre.substr(pos+1),in.substr(pos+1));//右子树
    cout<<pre[0];
}
 
int main()
{
    string pre,in;
    cin >> pre >> in;
    Traverse(pre,in);
    return 0;
}
```
### 18923 二叉树的直径
```cpp
#include <iostream>
#define For(i,a,b) for(int i=a;i<b;i++)
using namespace std;

typedef struct treenode
{
    int pn;//双亲结点所在下标
    int lchild=0;//左孩子
    int rchild=0;//右孩子
    int maxlen=1;//以该结点为根节点的子树的深度
} Tree;

Tree t[10005];

//A用于按输入顺序存储结点
int A[10005];
int main()
{
    int Ans=0,j=0;
    int n;
    cin>>n;
    For(i,1,n)
    {
        int p,c;
        cin>>p>>c;
        if(i==1)
            A[j++]=p;
        if(!t[p].lchild)//p的左孩子为空
        {
            t[c].pn=p;
            t[p].lchild=c;
        }
        else
        {
            t[c].pn=p;
            t[p].rchild=c;
        }
        A[j++]=c;

    }
    for(int i=j-1;i>=0;i--)
    {
        int l=0,r=0;
        if(t[A[i]].lchild)
          l=t[t[A[i]].lchild].maxlen;//左子树的深度
        if(t[A[i]].rchild)
          r=t[t[A[i]].rchild].maxlen;//右子树的深度
     t[A[i]].maxlen=max(l+1,r+1);//A[i]结点为根节点的子树的深度

//A[i]结点为根节点的子树的最大二叉树直径
        if(Ans<l+r)
            Ans=l+r;
    }
cout<<Ans<<endl;
return 0;
}
```

```cpp
#include <iostream>
 
typedef long long ll;
using namespace std;
int n,child[105][3],ans=0;
int dfs(int root)
{
    if(!root)
        return 0;
    int lchild=dfs(child[root][1]),rchild=dfs(child[root][2]);
    int len=max(lchild,rchild)+1;
    ans=max(ans,lchild+rchild);
    return len;
}
int main()
{
    int i,j,x,y;
    cin>>n;
    for(i=1; i<n; i++)
    {
        cin>>x>>y;
        if(!child[x][1])
            child[x][1]=y;
        else
            child[x][2]=y;
    }
    dfs(1);
    cout<<ans;
    return 0;
}
```
### 8609 哈夫曼树
```cpp

```

## 实验5
### 8610 顺序查找
```cpp
#include"malloc.h" /* malloc()等 */
#include"stdio.h"
#include"stdlib.h"

typedef int ElemType;
typedef struct /*静态查找表的顺序存储结构 */
{
	ElemType *elem; /* 数据元素存储空间基址,建表时按实际长度分配,0号单元留空 */
	int length; /* 表长度 */
}SSTable;

void Creat_Seq(SSTable &ST,int n)
{ /* 操作结果: 构造一个含n个数据元素的静态顺序查找表ST(数据来自数组r) */
	int i,temp;
	ST.elem=(ElemType *)malloc((n+1) * sizeof(ElemType)); /* 动态生成n个数据元素空间(0号单元不用) */
	if(!(ST).elem)
	{
		printf("ERROR\n");
		exit(0);
	} /*内存分配失败结束程序*/
	for(i=1;i<=n;i++)
	{
		scanf("%d",&temp);
		*(ST.elem+i)=temp; /* 依次赋值给ST */
	}
	ST.length=n;
}

int Search_Seq(SSTable &ST,ElemType key)
{ /* 在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为 */
/* 该元素在表中的位置,否则为0。算法9.1 */
  for(int i=ST.length;i>=1;i--){
    if(ST.elem[i]==key){
        return i;
    }
  }
  return 0;
}

main()
{
	SSTable ST;
	int loc,key;
	int n;
	scanf("%d",&n);
	Creat_Seq(ST,n);
	//printf("Please input the key value:");
	scanf("%d",&key);
	loc = Search_Seq(ST,key);
	if(loc!=0)
		printf("The element position is %d.\n",loc);
	else
		printf("The element is not exist.\n");
}
```

### 8621 二分查找
```cpp
#include"malloc.h" /* malloc()等 */
#include"stdio.h"
#include"stdlib.h"

const int N=1E6;
int a[N],n,flag=0;

int Search_Seq(int a[],int key)
{ /* 在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为 */
/* 该元素在表中的位置,否则为0。算法9.1 */
   if(key<a[0] || key>a[n]){
    return 0;
   }
  int l=0,r=n+1,mid;
  while(l+1!=r){
    mid = (l+r)/2;
    if(a[mid] < key){
        l=mid;
    }else{
        r=mid;
    }
  }
  if(a[l+1]!=key){
    return 0;
  }
  return l+1;
}

int main()
{
	int loc,key;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
        scanf("%d",a+i);
	}
	scanf("%d",&key);
	loc = Search_Seq(a,key);
	if(loc)//不能用loc的返回值来确定position是否存在,因为position可以等于0
		printf("The element position is %d.\n",loc-1);
	else
		printf("The element is not exist.\n");
    return 0;
}

#include"malloc.h" /* malloc()等 */
#include"stdio.h"
#include"stdlib.h"

const int N=1E6;
int a[N],n,flag=0;

int Search_Seq(int a[],int key)
{ /* 在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为 */
/* 该元素在表中的位置,否则为0。算法9.1 */
    if(key>a[n] || key<a[1]){
        return 0;
    }
  int l=0,r=n+1,mid;
  while(l+1!=r){
    mid = (l+r)/2;
    if(a[mid] < key){
        l=mid;
    }else{
        r=mid;
    }
  }
  if(a[l]<key&&a[l+1]>key){
    if(l==0&&a[l]==key){
        flag=1;
        return l;
    }
    return 0;
  }
  flag=1;
  return l;
}

int main()
{
	int loc,key;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
        scanf("%d",a+i);
	}
	scanf("%d",&key);
	loc = Search_Seq(a,key);
	if(flag)
		printf("The element position is %d.\n",loc);
	else
		printf("The element is not exist.\n");
    return 0;
}
```

### 8622 哈希查找
```cpp
#include"malloc.h" /* malloc()等 */
#include"stdlib.h" /* exit() */
#include"stdio.h"
#define EQ(a,b) ((a)==(b))
#define SUCCESS 1
#define UNSUCCESS 0
#define NULLKEY -1 /*哈希表无元素时值为-1*/
typedef int ElemType;
int length;
typedef struct
{
   ElemType *elem; /* 数据元素存储基址,动态分配数组 */
   int count; /* 当前数据元素个数 */
}HashTable;

void InitHashTable(HashTable *H)
 { /* 操作结果: 构造一个长度为length的哈希表,length为全局变量 */
   int i;
   (*H).count=0; /* 当前元素个数为0 */
   (*H).elem=(ElemType*)malloc(length*sizeof(ElemType));
   if(!(*H).elem)
     exit(0); /* 存储分配失败 */
   for(i=0;i<length;i++)
     (*H).elem[i]=NULLKEY; /* 未填记录的标志 */
}
unsigned Hash(ElemType K)
{ /* 一个简单的哈希函数*/
    return K = K*3%length;
}
void collision(int *p) /*线性探测再散列 */
{ /* 开放定址法处理冲突 */

    ((*p)++)%length;

}
int SearchHash(HashTable H,ElemType K,int *p,int *c)
{  /* 在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据 */
   /* 元素在表中位置,并返回SUCCESS;否则,以p指示插入位置,并返回UNSUCCESS */
   /* c用以计冲突次数,其初值置零,供建表插入时参考。算法9.17 */
   *p=Hash(K); /* 求得哈希地址 */
   while(H.elem[*p]!=NULLKEY&&!EQ(K,H.elem[*p]))
   { /* 该位置中填有记录,并且关键字不相等 */
     (*c)++;
     if(*c<length)
	   collision(p); /* 求得下一探查地址p */
     else
       break;
   }
   if EQ(K,H.elem[*p])
     return SUCCESS; /* 查找成功,p返回待查数据元素位置 */
   else
     return UNSUCCESS; /* 查找不成功(H.elem[p].key==NULLKEY),p返回的是插入位置 */
}
int InsertHash(HashTable *H,ElemType e)
{ /* 查找不成功时插入数据元素e到开放定址哈希表H中,并返回查找长度 */
   int c,p;
   c=0;
   if(SearchHash(*H,e,&p,&c))   /* 表中已有与e有相同关键字的元素 */
     printf("哈希表中已有元素%d。\n",e);
   else{ /* 插入e */
     (*H).elem[p]=e;
     ++(*H).count;
   }
   return c+1; /*查找长度为冲突次数加1*/
}
void TraverseHash(HashTable H)
 { /* 按哈希地址的顺序打印哈希表,无元素位置用X表示 */
   int i;
   //printf("HashTable Address:0~%d\n",length-1);
   for(i=0;i<length;i++)
     if(H.elem[i]==NULLKEY) /* 有数据 */
       printf("X ");
	 else
		 printf("%d ",H.elem[i]);
	 printf("\n");
}
main()
{
	float i=0,j=0;
	ElemType e;
	HashTable H;
         //printf("Input Table length:");
	scanf("%d",&length);
	InitHashTable(&H);
	//printf("Input key words sequence, -1 conclusion input:");
	scanf("%d",&e);
	while(e!=-1)
	{
		j ++;  /*j记录输入元素个数*/
		i = i + InsertHash(&H,e);  /*i记录查找长度的和*/
		scanf("%d",&e);
	}
	TraverseHash(H);
	printf("Average search length=%f\n",i/j);
}
```

### 8638 直接插入排序(8639 折半插入排序)
```cpp
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

int main() {
    int n,k,j;
    vector<int> a;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>k;
        a.push_back(k);
    }
    for(int i=1;i<n;i++){
        k = a[i];
        for(j=i-1;j>=0&&k<=a[j];j--){
            a[j+1] = a[j];
        }
        a[j+1] = k;
        for(int k=0;k<n;k++){
            cout<<a[k]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
```

### 8640 希尔(shell)排序
```cpp
void shell_sort(vector<int> a){
	int j,tmp;
	for(int gap = a.size()/2;gap>0;gap/=2){
		for(int i=gap;i<a.size();i++){
			tmp=a[i];
			for(j=i-gap;j>=0&&a[j]>tmp;j-=gap){
				a[j+gap] = a[j];
			}
			a[j+gap] = tmp;
		}
		for(auto x:a) cout<<x<<" ";
		cout<<endl;
	}
}
```

### 8641 冒泡排序
```cpp
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

int main() {
    int n,k,j;
    vector<int> a;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>k;
        a.push_back(k);
    }
    bool sorted = false;
    for(int i=1;i<n&&!sorted;i++){
        sorted=true;
        for(int j=0;j<n-1;j++){
            if(a[j]>a[j+1]){
                swap(a[j],a[j+1]);
                sorted = false;
            }
        }
        for(int k=0;k<n;k++){
            cout<<a[k]<<" ";
        }
        cout<<endl;
    }
    return 0;
}```

### 8642 快速排序
```cpp
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e5;
int n;
void insert_sort(int a[],int n){
    int i,j,temp;
    for(i=1;i<n;i++){
        temp =a[i];
        for(j=i-1;temp<=a[j]&&j>=0;j--){
            a[j+1] = a[j];
        }
        a[j+1] = temp;
        for(int j=0;j<n;j++){
            cout<<a[j]<<" ";
        }
        cout<<endl;
    }
}

void shell1_sort(int a[],int n){
    int gap = n,temp,j;
    while(gap>=1){
        gap/=2;
        if(gap<1) break;
        for(int i=gap;i<n;i++){
            temp = a[i];
            for(j=i-gap;j>=0&&a[j]>a[i];j-=gap){
                a[j+gap] = a[j];
            }
            a[j+gap] = temp;
        }
        for(int j=0;j<n;j++){
            cout<<a[j]<<" ";
        }
        cout<<endl;
    }
}

void shell2_sort(int arr[], int len)
{
    int i, j, gap, key;
    for(gap = len / 2; gap > 0; gap = gap / 2)
    {
        for(i = gap; i < len; i ++)
        {
            j = i - gap;
            key = arr[i];
            while(j >= 0 && arr[j] > key)
            {
                arr[j + gap] = arr[j];
                j -= gap;
            }
            arr[j + gap] = key;
        }
        for(int j=0;j<len;j++){
            cout<<arr[j]<<" ";
        }
        cout<<endl;
    }
}

void bubble_sort(int a[],int len){
    for(int i=0;i<len-1;i++){
        int flag = 1;
        for(int j=0;j<len-1-i;j++){
            if(a[j]>a[j+1]){
                swap(a[j],a[j+1]);
                flag=0;
            }
        }
        for(int j=0;j<len;j++){
            cout<<a[j]<<" ";
        }
        cout<<endl;
        if(flag) return;
    }
}

//int partition(vector<int>& arr, int left, int right) {
//    int pivot = arr[left];
//    while (left < right) {
//        while (left < right && arr[right] >= pivot) {
//            right--;
//        }
//        arr[left] = arr[right];
//        while (left < right && arr[left] <= pivot) {
//            left++;
//        }
//        arr[right] = arr[left];
//    }
//    arr[left] = pivot;
//    return left;
//}
//
//void quick_sort(vector<int>& arr, int left, int right) {
//    if (left < right) {
//        int pivot_index = partition(arr, left, right);
//        for (int i = 0; i < arr.size(); i++) {
//            cout << arr[i] << " ";
//        }
//        cout << endl;
//        quick_sort(arr, left, pivot_index - 1);
//        quick_sort(arr, pivot_index + 1, right);
//    }
//}

int partition(int a[],int left,int right){
	int pivot=a[left];
	while(left<right){
		while(left<right&&a[right]>=pivot){//注意等号 
			right--;
		}
		a[left] = a[right];
		while(left<right&&a[left]<=pivot){
			left++;
		}
		a[right] = a[left]; 
	}
	a[left] = pivot;
	return left;
}
void quick_sort(int a[],int left,int right){
	if(left<right){
		int pivot_index = partition(a,left,right);
		for(int i=0;i<n;i++){
			cout<<a[i]<<" ";
		}
		cout<<endl;
		quick_sort(a,left,pivot_index-1);
		quick_sort(a,pivot_index+1,right);
	}
} 
int main() {
    int a[N];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    quick_sort(a,0,n-1);
    return 0;
}
```

### 8643 简单选择排序
```cpp

void select_sort(int a[],int n){
	for(int i=0;i<n-1;i++){
		int min_index = i;
		for(int j=i+1;j<n;j++){
			if(a[j]<a[min_index]){
				min_index = j;
			}
		}
		swap(a[i],a[min_index]);
		for(int k=0;k<n;k++){
			cout<<a[k]<<" ";
		}
		cout<<endl;
	}
}
int main() {
    int a[N];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    select_sort(a,n);
    return 0;
}
```

### 8644 堆排序
```cpp
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e5;
int n,tmp[N];
void insert_sort(int a[],int n){
    int i,j,temp;
    for(i=1;i<n;i++){
        temp =a[i];
        for(j=i-1;temp<=a[j]&&j>=0;j--){
            a[j+1] = a[j];
        }
        a[j+1] = temp;
        for(int j=0;j<n;j++){
            cout<<a[j]<<" ";
        }
        cout<<endl;
    }
}

void shell1_sort(int a[],int n){
    int gap = n,temp,j;
    while(gap>=1){
        gap/=2;
        if(gap<1) break;
        for(int i=gap;i<n;i++){
            temp = a[i];
            for(j=i-gap;j>=0&&a[j]>a[i];j-=gap){
                a[j+gap] = a[j];
            }
            a[j+gap] = temp;
        }
        for(int j=0;j<n;j++){
            cout<<a[j]<<" ";
        }
        cout<<endl;
    }
}

void shell2_sort(int arr[], int len)
{
    int i, j, gap, key;
    for(gap = len / 2; gap > 0; gap = gap / 2)
    {
        for(i = gap; i < len; i ++)
        {
            j = i - gap;
            key = arr[i];
            while(j >= 0 && arr[j] > key)
            {
                arr[j + gap] = arr[j];
                j -= gap;
            }
            arr[j + gap] = key;
        }
        for(int j=0;j<len;j++){
            cout<<arr[j]<<" ";
        }
        cout<<endl;
    }
}

void bubble_sort(int a[],int len){
    for(int i=0;i<len-1;i++){
        int flag = 1;
        for(int j=0;j<len-1-i;j++){
            if(a[j]>a[j+1]){
                swap(a[j],a[j+1]);
                flag=0;
            }
        }
        for(int j=0;j<len;j++){
            cout<<a[j]<<" ";
        }
        cout<<endl;
        if(flag) return;
    }
}

//int partition(vector<int>& arr, int left, int right) {
//    int pivot = arr[left];
//    while (left < right) {
//        while (left < right && arr[right] >= pivot) {
//            right--;
//        }
//        arr[left] = arr[right];
//        while (left < right && arr[left] <= pivot) {
//            left++;
//        }
//        arr[right] = arr[left];
//    }
//    arr[left] = pivot;
//    return left;
//}
//
//void quick_sort(vector<int>& arr, int left, int right) {
//    if (left < right) {
//        int pivot_index = partition(arr, left, right);
//        for (int i = 0; i < arr.size(); i++) {
//            cout << arr[i] << " ";
//        }
//        cout << endl;
//        quick_sort(arr, left, pivot_index - 1);
//        quick_sort(arr, pivot_index + 1, right);
//    }
//}

int partition(int a[],int left,int right){
	int pivot=a[left];
	while(left<right){
		while(left<right&&a[right]>=pivot){//注意等号 
			right--;
		}
		a[left] = a[right];
		while(left<right&&a[left]<=pivot){
			left++;
		}
		a[right] = a[left]; 
	}
	a[left] = pivot;
	return left;
}

void quick_sort(int a[],int left,int right){
	if(left<right){
		int pivot_index = partition(a,left,right);
		for(int i=0;i<n;i++){
			cout<<a[i]<<" ";
		}
		cout<<endl;
		quick_sort(a,left,pivot_index-1);
		quick_sort(a,pivot_index+1,right);
	}
} 

void select_sort(int a[],int n){
	for(int i=0;i<n-1;i++){
		int min_index = i;
		for(int j=i+1;j<n;j++){
			if(a[j]<a[min_index]){
				min_index = j;
			}
		}
		swap(a[i],a[min_index]);
		for(int k=0;k<n;k++){
			cout<<a[k]<<" ";
		}
		cout<<endl;
	}
}

void merge_sort(int q[], int l, int r)//递归归并 
{
    if (l >= r) return;

    int mid = l + r >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);
	
	
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];

    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
    for(int m=0;m<n;m++){
			cout<<q[m]<<" ";
		}
	cout<<endl;
}



void HeapAdjust(int* arr, int start, int end)//下滤法,从上往下不断筛选 
{
	int root=arr[start];//记录根值,左孩子为2*i,右孩子为2*i+1; 
	for(int j=2*start;j<=end;j*=2){//start为根,j表示左孩子,不断寻找左孩子 
		if(j<end && arr[j] < arr[j+1]) j++;//左孩子小于右孩子,找到大孩子 
		if(root >= arr[j]) continue;//如果根的值 
		arr[start] = arr[j];
		start = j;
	} 
	arr[start] = root;
}

void creat_heap(int* a,int length){
	for(int i = length/2;i>0;--i){
		HeapAdjust(a,i,length);
	}
}
 
void heap_sort(int* arr, int len)
{
	creat_heap(arr,len);
	for(int i=len;i>1;i--){
		for(int k=1;k<=len;k++){
			cout<<arr[k]<<" ";
		}
		cout<<endl;
		swap(arr[i],arr[1]);
		HeapAdjust(arr,1,i-1);
	}
	for(int k=1;k<=len;k++){
			cout<<arr[k]<<" ";
		}
}

int main() {
    int a[N];
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    heap_sort(a,n);
    return 0;
}
```

### 8645 归并排序(非递归算法)
```cpp
#include <iostream>
#include <vector>
using namespace std;

void merge(vector<int>& arr, int left, int mid, int right) {
    vector<int> temp(right - left + 1);  // 临时数组,用来存储归并后的结果
    int i = left, j = mid + 1, 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++];
    }
    for (int i = 0; i < k; i++) {  // 将临时数组中的元素复制回原数组
        arr[left + i] = temp[i];
    }
}

void merge_sort(vector<int>& arr, int n) {
    for (int step = 1; step < n; step *= 2) {  // 步长从1开始,每次*2,直到大于等于n
        for (int left = 0; left < n - step; left += step * 2) {  // 每次对两个步长为step的子序列进行归并
            int mid = left + step - 1;
            int right = min(left + step * 2 - 1, n - 1);
            merge(arr, left, mid, right);
        }
        for (int i = 0; i < n; i++) {  // 输出每趟排序结果
            cout << arr[i] << " ";
        }
        cout << endl;
    }
}

int main() {
    int n;
    cin >> n;
    vector<int> arr(n);
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    merge_sort(arr, n);
    return 0;
}
```

### 8646 基数排序
```cpp
//#include <iostream>
//#include <cmath> 
//#include <vector>
//
//using namespace std;
//
获取数组中最大的数字的位数
//int getMaxDigit(vector<int> &nums) {
//    int maxNum = 0;
//    for (int num : nums) {
//        maxNum = max(maxNum, num);
//    }
//    int digit = 0;
//    while (maxNum > 0) {
//        maxNum /= 10;
//        digit++;
//    }
//    return digit;
//}
//
按照第d位进行排序
//void radixSort(vector<int> &nums, int d) {
//    //10个桶
//    vector<vector<int>> buckets(10); 
//    
//    //计算每一个数的第d位的值
//    for (int num : nums) {
//        int digit = (num / ((int)pow(10, d-1))) % 10;
//        buckets[digit].push_back(num);
//    }
//    
//    //把桶中的数放回nums
//    nums.clear();
//    for (vector<int> bucket : buckets) {
//        for (int num : bucket) {
//            nums.push_back(num);
//        }
//    }
//}
//
基数排序
//void radixSort(vector<int> &nums) {
//    //获取最大位数
//    int digit = getMaxDigit(nums);
//    
//    //进行digit次排序
//    for (int d = 1; d <= digit; d++) {
//        radixSort(nums, d);
//    }
//}
//
//int main() {
//    int n;
//    cin >> n;
//    vector<int> nums(n);
//    for (int i = 0; i < n; i++) {
//        cin >> nums[i];
//    }
//    
//    //基数排序
//    radixSort(nums);
//    
//    //输出结果
//    for (int num : nums) {
//        cout << num << " ";
//    }
//    cout << endl;
//}
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

int temp[100];
int bucket[10];

int maxBit(int data[],int n)
{
    int maxData = data[0];
    for(int i=1;i<n;i++)
    {
        if(maxData<data[i])
            maxData=data[i];
    }
    int d=1;
    while(maxData>=10)
    {
        maxData/=10;
        d++;
    }
    return d;
}

void radixsort(int data[],int n)
{
    int d = maxBit(data,n);
    int i,j,k;
    int radix = 1;
    for(i=1;i<=d;i++)
    {
        for(j=0;j<10;j++)
        {
            bucket[j]=0;
        }
        for(j=0;j<n;j++)
        {
            k=(data[j]/radix)%10;
            bucket[k]++;
        }
        
        for(j = 1; j < 10; j++)
            bucket[j] = bucket[j - 1] + bucket[j]; 
        
        for(j = n-1; j>=0; j--)
        {
            k = (data[j] / radix) % 10;
            temp[bucket[k] - 1] = data[j];
            bucket[k]--;
        }
        
        for(j = 0; j < n; j++){
        	int tmp=temp[j];
        	for(int k=d-1;k>=0;k--){
        	    cout<<tmp/int(pow(10,k));
        	    tmp%=int(pow(10,k));
			}
            cout<<" ";
        	
		}
        cout << endl;

        
        for(j = 0; j < n; j++)
            data[j] = temp[j];
            
        radix = radix * 10;
    } 
}

int main()
{
    int n, data[100];
    cin >> n;
    for(int i = 0; i < n; i++)
        cin >> data[i];
    radixsort(data, n);
    return 0;
}
```
## 实验7

### 8647 实现图的存储结构
```cpp
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <utility>
#include <vector>
#include <cmath>

using namespace std;
const int N = 1e3;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0)

int a[N][N];

int main(){
	IOS;
	int n,m,i,j;
	cin>>n>>m;
	while(m--){
		cin>>i>>j;
		a[i-1][j-1]=1;	
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}
```

### 8648 图的深度遍历
```cpp
#include"string.h" 
#include"malloc.h" /* malloc()等 */ 
#include"stdio.h" /* EOF(=^Z或F6),NULL */ 
#include"stdlib.h" /* exit() */ 
typedef int InfoType; /* 顶点权值类型 */ 
#define MAX_NAME 3 /* 顶点字符串的最大长度+1 */ 
typedef char VertexType[MAX_NAME]; /* 字符串类型 */ 
/*图的邻接表存储表示 */ 
#define MAX_VERTEX_NUM 20 
typedef enum{DG,DN,AG,AN}GraphKind; /* {有向图,有向网,无向图,无向网} */ 
typedef struct ArcNode 
{ 
	int adjvex; /* 该弧所指向的顶点的位置 */ 
	struct ArcNode *nextarc; /* 指向下一条弧的指针 */ 
	InfoType *info; /* 网的权值指针) */ 
}ArcNode; /* 表结点 */ 

typedef struct 
{ 
	VertexType data; /* 顶点信息 */ 
	ArcNode *firstarc; /* 第一个表结点的地址,指向第一条依附该顶点的弧的指针 */ 
}VNode,AdjList[MAX_VERTEX_NUM]; /* 头结点 */ 

typedef struct 
{ 
	AdjList vertices;//邻接表 
	int vexnum,arcnum; /* 图的当前顶点数和弧数 */ 
	int kind; /* 图的种类标志 */ 
}ALGraph; 

int LocateVex(ALGraph G,VertexType u) 
{ /* 初始条件: 图G存在,u和G中顶点有相同特征 */ 
/* 操作结果: 若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 */ 
	int i; 
	for(i=0;i<G.vexnum;++i) 
		if(strcmp(u,G.vertices[i].data)==0) 
			return i; 
	return -1; 
} 

void CreateGraph(ALGraph *G) 
{ /* 采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造4种图) */ 
	int i,j,k; 
	int w; /* 权值 */ 
	VertexType va,vb; 
	ArcNode *p; 
	//printf("Enter the type of map:(0~3): "); 
	scanf("%d",&(*G).kind); 
	//printf("Enter Vertex number,Arc number: "); 
	scanf("%d%d",&(*G).vexnum,&(*G).arcnum); 
	//printf("Enter %d Vertex :\n",(*G).vexnum); 
	for(i=0;i<(*G).vexnum;++i) /* 构造顶点向量 */ 
	{ 
		scanf("%s",(*G).vertices[i].data); 
		(*G).vertices[i].firstarc=NULL; 
	} 
	//if((*G).kind==1||(*G).kind==3) /* 网 */ 
	//	printf("Enter order every arc weight,head and tail (Takes the gap by the blank space ):\n"); 
	//else /* 图 */ 
	//	printf("Enter order every arc head and tail (Takes the gap by the blank space ):\n"); 
	for(k=0;k<(*G).arcnum;++k) /* 构造表结点链表 */ 
	{ 
		if((*G).kind==1||(*G).kind==3) /* 网 */ 
		scanf("%d%s%s",&w,va,vb); 
		else /* 图 */ 
		scanf("%s%s",va,vb); 
		i=LocateVex(*G,va); /* 弧尾 */ 
		j=LocateVex(*G,vb); /* 弧头 */ 
		p=(ArcNode*)malloc(sizeof(ArcNode)); 
		p->adjvex=j; 
		if((*G).kind==1||(*G).kind==3) /* 网 */ 
		{ 
			p->info=(int *)malloc(sizeof(int)); 
			*(p->info)=w; 
		} 
		else 
		p->info=NULL; /* 图 */ 
		p->nextarc=(*G).vertices[i].firstarc; /* 插在表头 */ 
		(*G).vertices[i].firstarc=p; 
		if((*G).kind>=2) /* 无向图或网,产生第二个表结点 */ 
		{ 
			p=(ArcNode*)malloc(sizeof(ArcNode)); 
			p->adjvex=i; 
			if((*G).kind==3) /* 无向网 */ 
			{ 
				p->info=(int*)malloc(sizeof(int)); 
				*(p->info)=w; 
			} 
			else 
			p->info=NULL; /* 无向图 */ 
			p->nextarc=(*G).vertices[j].firstarc; /* 插在表头 */ 
			(*G).vertices[j].firstarc=p; 
		} 
	}	 
} 

VertexType* GetVex(ALGraph G,int v) 
{ /* 初始条件: 图G存在,v是G中某个顶点的序号。操作结果: 返回v的值 */ 
	if(v>=G.vexnum||v<0) 
		exit(0); 
	return &G.vertices[v].data; 
} 

int FirstAdjVex(ALGraph G,VertexType v) 
{ /* 初始条件: 图G存在,v是G中某个顶点 */ 
/* 操作结果: 返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 */ 
	ArcNode *p; 
	int v1; 
	v1=LocateVex(G,v); /* v1为顶点v在图G中的序号 */ 
	p=G.vertices[v1].firstarc; 
	if(p) 
		return p->adjvex; 
	else 
		return -1; 
} 

int NextAdjVex(ALGraph G,VertexType v,VertexType w) 
{ /* 初始条件: 图G存在,v是G中某个顶点,w是v的邻接顶点 */ 
/* 操作结果: 返回v的(相对于w的)下一个邻接顶点的序号。 */ 
/* 若w是v的最后一个邻接点,则返回-1 */ 
	ArcNode *p; 
	int v1,w1; 
	v1=LocateVex(G,v); /* v1为顶点v在图G中的序号 */ 
	w1=LocateVex(G,w); /* w1为顶点w在图G中的序号 */ 
	p=G.vertices[v1].firstarc; 
	while(p&&p->adjvex!=w1) /* 指针p不空且所指表结点不是w */ 
		p=p->nextarc; 
	if(!p||!p->nextarc) /* 没找到w或w是最后一个邻接点 */ 
		return -1; 
	else /* p->adjvex==w */ 
		return p->nextarc->adjvex; /* 返回v的(相对于w的)下一个邻接顶点的序号 */ 
} 

/*深度遍历*/ 
int visited[MAX_VERTEX_NUM]; /* 访问标志数组(全局量),未访问标记0,访问标记1 */ 
void(*VisitFunc)(char* v); /* 函数变量(全局量) */ 
void DFS(ALGraph G,int v) 
{ /* 从第v个顶点出发递归地深度优先遍历图G。算法7.5 */ 
/* 设置访问标志为TRUE(已访问) */ 
/* 访问第v个顶点 */ 
/* 对v的尚未访问的邻接点w递归调用DFS 
*/ 
	visited[v] = true;
	VisitFunc(G.vertices[v].data);
	for(int w = FirstAdjVex(G,G.vertices[v].data);w>0;w=NextAdjVex(G,G.vertices[v].data,G.vertices[w].data)){
		if(!visited[w]) DFS(G,w);
	}
}

void print(char* i){
	printf("%s ",i);
}
 
void DFSTraverse(ALGraph G,void(*Visit)(char*)) 
{ /* 对图G作深度优先遍历。算法7.4 */ 
/* 使用全局变量VisitFunc,使DFS不必设函数指针参数 */ 
/* 访问标志数组初始化 */ 
/* 对尚未访问的顶点调用DFS */ 
	VisitFunc = Visit;
	for(int v=0;v<G.vexnum;v++) visited[v] = false;
	for(int v=0;v<G.vexnum;v++) {
		if(!visited[v]) DFS(G,v);
	} 
	printf("\n"); 
} 



int main() 
{ 
	ALGraph g; 
	CreateGraph(&g); 
	DFSTraverse(g,print); 
	return 1;
}
```

### 8649 图的广度遍历
```cpp
#include"string.h" 
#include"malloc.h" /* malloc()等 */ 
#include"stdio.h" /* EOF(=^Z或F6),NULL */ 
#include"stdlib.h" /* exit() */ 
typedef int InfoType; /* 顶点权值类型 */ 
#define MAX_NAME 3 /* 顶点字符串的最大长度+1 */ 
typedef char VertexType[MAX_NAME]; /* 字符串类型 */ 
/*图的邻接表存储表示 */ 
#define MAX_VERTEX_NUM 20 
typedef enum{DG,DN,AG,AN}GraphKind; /* {有向图,有向网,无向图,无向网} */ 
typedef struct ArcNode 
{ 
	int adjvex; /* 该弧所指向的顶点的位置 */ 
	struct ArcNode *nextarc; /* 指向下一条弧的指针 */ 
	InfoType *info; /* 网的权值指针) */ 
}ArcNode; /* 表结点 */ 

typedef struct 
{ 
	VertexType data; /* 顶点信息 */ 
	ArcNode *firstarc; /* 第一个表结点的地址,指向第一条依附该顶点的弧的指针 */ 
}VNode,AdjList[MAX_VERTEX_NUM]; /* 头结点 */ 

typedef struct 
{ 
	AdjList vertices;//邻接表 
	int vexnum,arcnum; /* 图的当前顶点数和弧数 */ 
	int kind; /* 图的种类标志 */ 
}ALGraph; 

int LocateVex(ALGraph G,VertexType u) 
{ /* 初始条件: 图G存在,u和G中顶点有相同特征 */ 
/* 操作结果: 若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 */ 
	int i; 
	for(i=0;i<G.vexnum;++i) 
		if(strcmp(u,G.vertices[i].data)==0) 
			return i; 
	return -1; 
} 

void CreateGraph(ALGraph *G) 
{ /* 采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造4种图) */ 
	int i,j,k; 
	int w; /* 权值 */ 
	VertexType va,vb; 
	ArcNode *p; 
	//printf("Enter the type of map:(0~3): "); 
	scanf("%d",&(*G).kind); 
	//printf("Enter Vertex number,Arc number: "); 
	scanf("%d%d",&(*G).vexnum,&(*G).arcnum); 
	//printf("Enter %d Vertex :\n",(*G).vexnum); 
	for(i=0;i<(*G).vexnum;++i) /* 构造顶点向量 */ 
	{ 
		scanf("%s",(*G).vertices[i].data); 
		(*G).vertices[i].firstarc=NULL; 
	} 
	//if((*G).kind==1||(*G).kind==3) /* 网 */ 
	//	printf("Enter order every arc weight,head and tail (Takes the gap by the blank space ):\n"); 
	//else /* 图 */ 
	//	printf("Enter order every arc head and tail (Takes the gap by the blank space ):\n"); 
	for(k=0;k<(*G).arcnum;++k) /* 构造表结点链表 */ 
	{ 
		if((*G).kind==1||(*G).kind==3) /* 网 */ 
		scanf("%d%s%s",&w,va,vb); 
		else /* 图 */ 
		scanf("%s%s",va,vb); 
		i=LocateVex(*G,va); /* 弧尾 */ 
		j=LocateVex(*G,vb); /* 弧头 */ 
		p=(ArcNode*)malloc(sizeof(ArcNode)); 
		p->adjvex=j; 
		if((*G).kind==1||(*G).kind==3) /* 网 */ 
		{ 
			p->info=(int *)malloc(sizeof(int)); 
			*(p->info)=w; 
		} 
		else 
		p->info=NULL; /* 图 */ 
		p->nextarc=(*G).vertices[i].firstarc; /* 插在表头 */ 
		(*G).vertices[i].firstarc=p; 
		if((*G).kind>=2) /* 无向图或网,产生第二个表结点 */ 
		{ 
			p=(ArcNode*)malloc(sizeof(ArcNode)); 
			p->adjvex=i; 
			if((*G).kind==3) /* 无向网 */ 
			{ 
				p->info=(int*)malloc(sizeof(int)); 
				*(p->info)=w; 
			} 
			else 
			p->info=NULL; /* 无向图 */ 
			p->nextarc=(*G).vertices[j].firstarc; /* 插在表头 */ 
			(*G).vertices[j].firstarc=p; 
		} 
	}	 
} 

VertexType* GetVex(ALGraph G,int v) 
{ /* 初始条件: 图G存在,v是G中某个顶点的序号。操作结果: 返回v的值 */ 
	if(v>=G.vexnum||v<0) 
		exit(0); 
	return &G.vertices[v].data; 
} 

int FirstAdjVex(ALGraph G,VertexType v) 
{ /* 初始条件: 图G存在,v是G中某个顶点 */ 
/* 操作结果: 返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 */ 
	ArcNode *p; 
	int v1; 
	v1=LocateVex(G,v); /* v1为顶点v在图G中的序号 */ 
	p=G.vertices[v1].firstarc; 
	if(p) 
		return p->adjvex; 
	else 
		return -1; 
} 

int NextAdjVex(ALGraph G,VertexType v,VertexType w) 
{ /* 初始条件: 图G存在,v是G中某个顶点,w是v的邻接顶点 */ 
/* 操作结果: 返回v的(相对于w的)下一个邻接顶点的序号。 */ 
/* 若w是v的最后一个邻接点,则返回-1 */ 
	ArcNode *p; 
	int v1,w1; 
	v1=LocateVex(G,v); /* v1为顶点v在图G中的序号 */ 
	w1=LocateVex(G,w); /* w1为顶点w在图G中的序号 */ 
	p=G.vertices[v1].firstarc; 
	while(p&&p->adjvex!=w1) /* 指针p不空且所指表结点不是w */ 
		p=p->nextarc; 
	if(!p||!p->nextarc) /* 没找到w或w是最后一个邻接点 */ 
		return -1; 
	else /* p->adjvex==w */ 
		return p->nextarc->adjvex; /* 返回v的(相对于w的)下一个邻接顶点的序号 */ 
} 

/*深度遍历*/ 
int visited[MAX_VERTEX_NUM]; /* 访问标志数组(全局量),未访问标记0,访问标记1 */ 
void(*VisitFunc)(char* v); /* 函数变量(全局量) */ 
void DFS(ALGraph G,int v) 
{ /* 从第v个顶点出发递归地深度优先遍历图G。算法7.5 */ 
/* 设置访问标志为TRUE(已访问) */ 
/* 访问第v个顶点 */ 
/* 对v的尚未访问的邻接点w递归调用DFS 
*/ 
	visited[v] = true;
	VisitFunc(G.vertices[v].data);
	for(int w = FirstAdjVex(G,G.vertices[v].data);w>0;w=NextAdjVex(G,G.vertices[v].data,G.vertices[w].data)){
		if(!visited[w]) DFS(G,w);
	}
}

void print(char* i){
	printf("%s ",i);
}
 
void DFSTraverse(ALGraph G,void(*Visit)(char*)) 
{ /* 对图G作深度优先遍历。算法7.4 */ 
/* 使用全局变量VisitFunc,使DFS不必设函数指针参数 */ 
/* 访问标志数组初始化 */ 
/* 对尚未访问的顶点调用DFS */ 
	VisitFunc = Visit;//对全局变量函数进行赋值,将传入的函数赋值为全局函数,便于DFS函数调用 
	for(int v=0;v<G.vexnum;v++) visited[v] = false;
	for(int v=0;v<G.vexnum;v++) {
		if(!visited[v]) DFS(G,v);//如果该节点没有被访问过,就继续找 
	} 
	printf("\n"); 
} 


int main() 
{ 
	ALGraph g; 
	CreateGraph(&g); 
	DFSTraverse(g,print); 
	return 1;
}
```

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值