6-1 顺序表的删除操作
//删除顺序表第i个位置的元素
int del(SeqList *sq,int i){
if (i < 1 || i > sq->n ){
return -1;
}
for (int j = i;j < sq->n;j++){
sq->a[j - 1] = sq->a[j];
}
sq->n--;
return 1;
}
6-2 求链式表的表长
int Length( List L ){
int num;
List p = L;
while (p != NULL){
num++;
p = p->Next;
}
return num;
}
6-3 递增的整数序列链表的插入
List Insert( List L, ElementType X )
{
List p, q, r; // 定义三个指针,分别指向当前结点、前一个结点和新结点
p = L->Next; // p指向第一个数据结点
q = L; // q指向头结点
while (p && p->Data < X) // 在链表中寻找插入位置,使得q->Data < X <= p->Data
{
q = p; // q指向p的前一个结点
p = p->Next; // p指向下一个结点
}
r = (List)malloc(sizeof(struct Node)); // 为新结点分配空间
r->Data = X; // 存储数据
r->Next = p; // 新结点的下一个结点指向p
q->Next = r; // 前一个结点的下一个结点指向r
return L; // 返回链表头指针
}
6-4 查找中间结点
Node* find_middle(Node* head)
{
int count = 0;
Node *p = head;
if(p == NULL)
return p;
while(p->next != NULL)
{
count++;
p = p->next;
}
p = head;
count = count/2;
while(count > 0)
{
p = p->next;
count--;
}
return p;
}
6-5 求链表的倒数第m个元素
ElementType Find( List L, int m )
{
List p, q; // 定义两个指针,分别指向前后结点
p = q = L->Next; // 初始时都指向第一个数据结点
int i = 0; // 定义一个计数器,记录结点的位置
while (p) // 当前结点不为空时,循环继续
{
if (i >= m) // 如果计数器大于等于m,说明后结点已经到达倒数第m个位置
{
q = q->Next; // 后结点向后移动一位
}
p = p->Next; // 前结点向后移动一位
i++; // 计数器加一
}
if (i < m) // 如果计数器小于m,说明链表长度不足m,返回错误标志
{
return ERROR;
}
else // 否则,返回后结点的数据
{
return q->Data;
}
}
6-6 链表逆置
struct ListNode *reverse( struct ListNode *head )
{
struct ListNode *prev, *curr, *next; // 定义三个指针,分别指向前一个结点、当前结点和下一个结点
prev = NULL; // 初始时,前一个结点为空
curr = head; // 初始时,当前结点为头结点
while (curr) // 当当前结点不为空时,循环继续
{
next = curr->next; // 保存下一个结点的地址
curr->next = prev; // 将当前结点的下一个结点指向前一个结点,实现逆置
prev = curr; // 前一个结点后移一位
curr = next; // 当前结点后移一位
}
return prev; // 当前结点为空时,前一个结点指向的就是逆置后的链表头,返回其地址
}
6-7 两个有序链表序列的合并
List Merge( List L1, List L2 )
{
List L, p, q, r;
L = (List)malloc(sizeof(struct Node)); // 创建一个新的头结点
L->Next = NULL; // 初始化为空链表
r = L; // r指向当前的尾结点
p = L1->Next; // p指向L1的第一个数据结点
q = L2->Next; // q指向L2的第一个数据结点
while (p && q) // 当两个链表都有数据时
{
if (p->Data <= q->Data) // 如果p的数据小于等于q的数据
{
r->Next = p; // 将p接到L的尾部
r = p; // r指向新的尾结点
p = p->Next; // p指向下一个结点
}
else // 如果p的数据大于q的数据
{
r->Next = q; // 将q接到L的尾部
r = q; // r指向新的尾结点
q = q->Next; // q指向下一个结点
}
}
if (p) // 如果L1还有剩余的结点
{
r->Next = p; // 将L1的剩余部分接到L的尾部
}
if (q) // 如果L2还有剩余的结点
{
r->Next = q; // 将L2的剩余部分接到L的尾部
}
L1->Next = NULL; // 将L1置为空链表
L2->Next = NULL; // 将L2置为空链表
return L; // 返回合并后的链表的头指针
}
6-8 另类堆栈
bool Push(Stack S, ElementType X)
{
if (S->Top == S->MaxSize)//判满条件
{
printf("Stack Full\n");
return false;
}
S->Data[S->Top++] = X;
return true;
}
ElementType Pop(Stack S)
{
if (S->Top == 0)//判空条件
{
printf("Stack Empty\n");
return ERROR;
}
return S->Data[--S->Top];
}
6-9 简单表达式求值
int cal( char a[] ) {
int num1 = 0, num2 = 0;
char op;
int i = 0;
while(a[i] != '+' && a[i] != '-' && a[i] != '*' && a[i] != '/') {
num1 = num1 * 10 + (a[i] - '0');
i++;
}
op = a[i];
i++;
while(a[i] != '=') {
num2 = num2 * 10 + (a[i] - '0');
i++;
}
switch(op) {
case '+': return num1 + num2;
case '-': return num1 - num2;
case '*': return num1 * num2;
case '/': return num1 / num2;
}
return 0;
}
6-10 另类循环队列
/* 你的代码将被嵌在这里 */
bool AddQ( Queue Q, ElementType X )
{
if (Q->Count == Q->MaxSize) // 如果队列已满
{
printf("Queue Full\n"); // 输出提示信息
return false; // 返回false
}
else // 如果队列未满
{
Position rear = (Q->Front + Q->Count) % Q->MaxSize; // 计算队列的尾指针
Q->Data[rear] = X; // 将元素X存入队列尾部
Q->Count++; // 队列中元素个数加一
return true; // 返回true
}
}
ElementType DeleteQ( Queue Q )
{
if (Q->Count == 0) // 如果队列为空
{
printf("Queue Empty\n"); // 输出提示信息
return ERROR; // 返回ERROR
}
else // 如果队列非空
{
ElementType X = Q->Data[Q->Front]; // 取出队列头部元素
Q->Front = (Q->Front + 1) % Q->MaxSize; // 队列头指针加一
Q->Count--; // 队列中元素个数减一
return X; // 返回出队元素
}
}
6-11 求二叉树高度
int GetHeight( BinTree BT )
{
if (BT == NULL)
return 0;
int leftHeight = GetHeight(BT->Left);
int rightHeight = GetHeight(BT->Right);
int height = 1 + (leftHeight > rightHeight ? leftHeight : rightHeight);
return height;
}
6-12 先序输出叶结点
void PreorderPrintLeaves( BinTree BT )
{
if (BT == NULL)
return;
if (BT->Left == NULL && BT->Right == NULL)
printf(" %c", BT->Data);
PreorderPrintLeaves(BT->Left);
PreorderPrintLeaves(BT->Right);
}
6-14 统计二叉树结点个数
/* 你的代码将被嵌在这里 */
int NodeCount ( BiTree T)
{
if (T == NULL) // 如果树为空
return 0; // 返回0
else // 如果树非空
return 1 + NodeCount(T->lchild) + NodeCount(T->rchild); // 返回根结点加上左右子树的结点个数之和
}
6-15 统计二叉树度为1的结点个数
int NodeCount( BiTree T){
if(T==NULL) {
return 0;
}
if(T->lchild==NULL&&T->rchild!=NULL||T->rchild==NULL&&T->lchild!=NULL){
return 1+NodeCount(T->lchild)+NodeCount(T->rchild);
}
return NodeCount(T->lchild)+NodeCount(T->rchild);
}
6-16 求采用邻接矩阵作为存储结构的无向图各顶点的度
void degree(MGraph G){
for(int i = 0;i<G.vexnum;i++){
int count = 0;
printf("%c:",G.vexs[i]);
for(int j = 0;j<G.vexnum;j++){
if(G.arcs[j][i]||G.arcs[i][j]) count++;
}
printf("%d\n",count);
}
}
6-17 求采用邻接矩阵作为存储结构的有向图各顶点的入度
void indegree(MGraph G)
{
for(int i = 0;i<G.vexnum;i++){
int count = 0;
printf("%c:",G.vexs[i]);
for(int j = 0;j<G.vexnum;j++){
if(G.arcs[j][i]) count++;
}
printf("%d\n",count);
}
}
6-18 邻接矩阵存储图的深度优先遍历
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) ) {
/* 用访问标记数组Visited,其初值为false */
Vertex W;
Visit( V ); /* 访问第V个顶点 */
Visited[V] = true; /* 标记V已访问 */
/* 对V的每个邻接点W */
for ( W=0; W<Graph->Nv; W++ ) {
/* 若W是V的邻接点并且未访问过 */
if ( Graph->G[V][W]!=INFINITY && !Visited[W] )
DFS( Graph, W, Visit ); /* 则递归访问之 */
}
}
6-19 图的深度遍历-邻接表实现
void DFS(ALGraph *G, int i)
{
printf(" %d", i);
visited[i] = 1;
struct ArcNode *w;
for (w = G->vertices[i].firstarc; w; w = w->nextarc)
{
if (visited[w->adjvex] == 0)
DFS(G, w->adjvex);
}
}
6-20 图的广度遍历-邻接矩阵实现
void BFS(MGraph G,Vertex v){
int q[1000],front = 0,rear = 0;
printf(" %d",v);
visited[v] = 1;
q[rear++] = v;
while(front!=rear){
int u = q[front++];//出队
for(int w = 0;w<G.vexnum;w++){
if(G.arcs[u][w]&&!visited[w]){
printf(" %d",w);
visited[w] = 1;
q[rear++] = w;
}
}
}
}
6-21 邻接表存储图的广度优先遍历
void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ){
Visit(S);
Visited[S]=true;
int a[1000]={0};
int end=0;
int begin=0;
a[end++]=S;
while(begin<end){
PtrToAdjVNode cur = Graph->G[a[begin++]].FirstEdge;
while(cur){
if(!Visited[cur->AdjV]){
Visit(cur->AdjV);
Visited[cur->AdjV]= true;
a[end++]=cur->AdjV;
}
cur=cur->Next;
}
}
}
7-1 字符串的冒泡排序
#include <stdio.h>
#include <string.h>
// 交换两个字符串的位置
void swap(char *a, char *b) {
char temp[11];
strcpy(temp, a);
strcpy(a, b);
strcpy(b, temp);
}
// 冒泡排序法对字符串序列进行排序
void bubble_sort(char arr[][11], int n, int k) {
int i, j;
for (i = 0; i < k; i++) {
for (j = 0; j < n - i - 1; j++) {
// 如果前一个字符串字典序大于后一个字符串,就交换它们的位置
if (strcmp(arr[j], arr[j + 1]) > 0) {
swap(arr[j], arr[j + 1]);
}
}
}
}
int main() {
int n, k, i;
char arr[100][11];
// 读入n和k
scanf("%d %d", &n, &k);
// 读入n个字符串
for (i = 0; i < n; i++) {
scanf("%s", arr[i]);
}
// 对字符串序列进行冒泡排序
bubble_sort(arr, n, k);
// 输出扫描完第k遍后的中间结果序列
for (i = 0; i < n; i++) {
printf("%s\n", arr[i]);
}
return 0;
}
7-3 括号匹配
#include <stdio.h>
#include <string.h>
int main() {
char str[101];
int stack[101], top = 0;
fgets(str, 101, stdin);
for (int i = 0; i < strlen(str); i++) {
if (str[i] == '(' || str[i] == '[' || str[i] == '{') {
stack[top++] = str[i];
} else if (str[i] == ')' || str[i] == ']' || str[i] == '}') {
if (top == 0) {
printf("no\n");
return 0;
}
char match;
if (str[i] == ')') match = '(';
if (str[i] == ']') match = '[';
if (str[i] == '}') match = '{';
if (stack[--top] != match) {
printf("no\n");
return 0;
}
}
}
if (top == 0) {
printf("yes\n");
} else {
printf("no\n");
}
return 0;
}
7-4 表达式求值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char expression[21];
double stack[21];
int top = -1;
while (scanf("%s", expression) != EOF) {
for (int i = 0; i < strlen(expression); i++) {
if (expression[i] >= '0' && expression[i] <= '9') {
stack[++top] = expression[i] - '0';
} else {
double b = stack[top--];
double a = stack[top--];
switch (expression[i]) {
case '+':
stack[++top] = a + b;
break;
case '-':
stack[++top] = a - b;
break;
case '*':
stack[++top] = a * b;
break;
case '/':
stack[++top] = a / b;
break;
}
}
}
printf("%.2f\n", stack[top--]);
}
return 0;
}
7-5 队的基本操作
#include <stdio.h>
#define MAX_SIZE 10
typedef struct {
int queue[MAX_SIZE];
int front, rear;
} Queue;
void initialize(Queue *q) {
q->front = q->rear = 0;
}
int isEmpty(Queue *q) {
return q->front == q->rear;
}
int isFull(Queue *q) {
return (q->rear + 1) % MAX_SIZE == q->front;
}
void enqueue(Queue *q, int value) {
if (!isFull(q)) {
q->queue[q->rear] = value;
q->rear = (q->rear + 1) % MAX_SIZE;
}
}
int dequeue(Queue *q) {
if (!isEmpty(q)) {
int value = q->queue[q->front];
q->front = (q->front + 1) % MAX_SIZE;
return value;
}
return 0;
}
int main() {
Queue q;
initialize(&q);
int n, operation;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &operation);
if (operation == 0) {
int value = dequeue(&q);
if (value == 0) {
printf("EMPTY ");
} else {
printf("%d ", value);
}
} else {
if (!isFull(&q)) {
enqueue(&q, operation);
} else {
printf("FULL ");
}
}
}
printf("\n");
while (!isEmpty(&q)) {
int value = dequeue(&q);
printf("%d ", value);
}
printf("\n");
return 0;
}
7-6 银行业务队列简单模拟
#include <iostream>
#include <queue>
using namespace std;
int main() {
int N;
cin >> N;
queue<int> A, B;
for(int i = 0; i < N; i++) {
int num;
cin >> num;
if(num % 2 == 1) A.push(num);
else B.push(num);
}
int i = 0;
while(!A.empty() || !B.empty()) {
if(!A.empty()) {
if (i > 0){
cout << " ";
}
cout << A.front();
A.pop();
i++;
}
if(!A.empty()) {
cout << " "<< A.front() ;
A.pop();
i++;
}
if(!B.empty()) {
if (i > 0){
cout << " ";
}
cout << B.front();
B.pop();
i++;
}
}
return 0;
}
7-7 h0181. 约瑟夫问题
#include <stdio.h>
int josephus(int n, int m) {
int result = 0;
for (int i = 2; i <= n; i++) {
result = (result + m) % i;
}
return result + 1;
}
int main() {
int n, m;
while (1) {
scanf("%d %d", &n, &m);
if (n == 0 && m == 0) {
break;
}
printf("%d\n", josephus(n, m));
}
return 0;
}
7-9 还原二叉树
#include <stdio.h>
#include <string.h>
typedef struct node {
char data;
struct node *left, *right;
} Node;
Node* build(char* pre, char* in, int len) {
if (len == 0) return NULL;
Node* root = (Node*)malloc(sizeof(Node));
root->data = pre[0];
int pos = strchr(in, pre[0]) - in;
root->left = build(pre + 1, in, pos);
root->right = build(pre + pos + 1, in + pos + 1, len - pos - 1);
return root;
}
int height(Node* root) {
if (root == NULL) return 0;
int leftHeight = height(root->left);
int rightHeight = height(root->right);
return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
int main() {
int N;
scanf("%d", &N);
char pre[N + 1], in[N + 1];
scanf("%s%s", pre, in);
Node* root = build(pre, in, N);
printf("%d\n", height(root));
return 0;
}
7-10 插入排序
#include <stdio.h>
#define MAXN 100
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d", arr[i]);
if (i < n - 1) printf(" ");
}
printf("\n"); //输出换行符
}
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
printArray(arr, n);
}
}
int main() {
int n;
int arr[MAXN];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
insertionSort(arr, n);
return 0;
}