实验一
- 实验名称。
用链式存储结构实现将m个有序表合并成一个有序表。
- 相关理论
单链表的合并,链表的定义和链表初始化和输出。
- 关键代码。
#include <iostream>
#include <algorithm>
#include <vector>
#include <stdio.h>
using namespace std;
typedef struct LinkList {
int data;
struct LinkList* next;
}Data;
void print_list(Data* head) {
while (head) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
Data* insert_tail(Data* head, int n) {
head = (Data*)malloc(sizeof(Data));
head->next = NULL;
Data* r = head;
while (n--) {
Data* p = (Data*)malloc(sizeof(Data));
int data;
scanf_s("%d", &data);
p->data = data;
r->next = p;
r = p;
p->next = NULL;
}
return head->next;
}
Data* merge_two_list(Data* headA, Data* headB) {
Data p;
p.data = 0;
p.next = NULL;
Data* result = &p;
while (headA && headB) {
if (headA->data < headB->data) {
result->next = headA;
headA = headA->next;
}
else {
result->next = headB;
headB = headB->next;
}
result = result->next;
}
if (headA == NULL) {
result->next = headB;
}
if (headB == NULL) {
result->next = headA;
}
return p.next;
}
Data* merge_list(vector<Data*>& list) {
if (list.size() == 0) {
return NULL;
}
if (list.size() == 1) {
return list[0];
}
int mid = list.size() / 2;
int i;
vector <Data*> sub_list1, sub_list2;
for (i = 0; i < mid; ++i) {
sub_list1.push_back(list[i]);
}
for (i = mid; i < list.size(); ++i) {
sub_list2.push_back(list[i]);
}
Data* list1 = merge_list(sub_list1);
Data* list2 = merge_list(sub_list2);
return merge_two_list(list1, list2);
}
bool cmp(Data* A, Data* B) {
return A->data < B->data;
}
Data* merge_list2(vector<Data*>& list) {
if (list.size() == 0) {
return NULL;
}
if (list.size() == 1) {
return list[0];
}
vector<Data*> result;
for (int i = 0; i < list.size(); ++i) {
while (list[i]) {
result.push_back(list[i]);
list[i] = list[i]->next;
}
}
sort(result.begin(), result.end(), cmp);
return result[0];
}
int main() {
vector<Data*> list;
printf("input the num of the construct list \n");
int num;
scanf_s("%d", &num);
for (int i = 0; i < num; ++i) {
Data* p{};
printf("construct the %d list:\n", i + 1);
list.push_back(insert_tail(p, 3));
}
printf("merget the mulity list with method 1 is \n");
Data* result = merge_list(list);
print_list(result);
printf("merge the mulity list with method 2 is \n");
Data* result2 = merge_list2(list);
print_list(result2);
return 0;
}
- 实验结果与分析。
实验二
- 实验目的。
已知线性表中的元素是无序的,并以带头结点的单链表作为存储结构。删除表中所有值大于min小于max的元素(若表中存在这样的元素)。
- 相关理论
单链表的遍历,排序,以及单链表的查找。
- 关键代码。
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef int Status;
typedef struct LNode
{
ElemType data;
LNode* next;
}LNode, * LinkList;
Status InitList(LinkList& L)
{
L = (LNode*)malloc(sizeof(LNode));
L->next = NULL;
return true;
}
Status CreateList(LinkList& L, int e)
{
LinkList p = L;
while (p->next)
p = p->next;
LinkList temp = (LinkList)malloc(sizeof(LNode));
temp->data = e;
temp->next = NULL;
p->next = temp;
return true;
}
Status DispList(LinkList& L)
{
LinkList p = L->next;
int i = 0;
while (p)
{
printf("%d\t", p->data);
i++;
p = p->next;
}
return true;
}
Status DeleteMiddleElem(LinkList& L, int mink, int maxk)
{
LinkList p, q, prev = L;
if (mink > maxk)return false;
p = L->next;
while (p != NULL)
{
if (p->data > mink && p->data < maxk)
{
prev->next = p->next;
q = p;
p = p->next;
free(q);
}
else
{
prev = p;
p = p->next;
}
}
return true;
}
int main()
{
int a[50], length = 0, min, max;
char flag = ' ';
printf("请输入一个线性表:");
for (int i = 0; flag == ' '; i++)
{
scanf_s("%d", &a[i]);
flag = getchar();
length++;
}
LinkList L;
InitList(L);
for (int i = 0; i < length; i++)
CreateList(L, a[i]);
printf("请输入裁剪区间:min max\n");
scanf_s("%d %d", &min, &max);
DeleteMiddleElem(L, min, max);
printf("裁剪后的结果为:\n");
DispList(L);
getchar();
system("pause");
return true;
}
- 实验结果与分析。
实验三
- 实验目的。
设计在无头结点的单链表中删除第i个节点的程序。
- 相关理论
单链表的遍历;无头结点单链表的定位;单链表的删除相关操作
- 关键代码。
#include<stdio.h>
#include<stdlib.h>
#define OK 1
typedef int Status;
typedef int ElemType;
typedef struct LNode
{
ElemType data;
LNode* next;
}LNode, * LinkList;
Status InitList(LinkList& L)
{
L = (LNode*)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}//InitList
Status CreateList(LinkList& L, int e)
{
LinkList p = L;
while (p->next)
p = p->next;
LinkList temp = (LinkList)malloc(sizeof(LNode));
temp->data = e;
temp->next = NULL;
p->next = temp;
return OK;
}//CreateList
Status DispList(LinkList& L)
{
LinkList p = L->next;
int i = 0;
while (p)
{
printf("%d\t", p->data);
i++;
p = p->next;
}
return OK;
}//DispList
Status Delete(LinkList& L, int i)
{
LinkList p{};
if (i == 0)
{
L = p->next;
}
else
{
p = L;
while (i > 0)
{
p = p->next;
i--;
}
p->next = p->next->next;
}
return OK;
}// Delete
int main()
{
int j, k;
LinkList L;
InitList(L);
for (int i = 0; i < 10; i++)
{
scanf_s("%d", &k);
CreateList(L, k);
}
printf("链表ha的元素有:\n");
DispList(L);
printf("\n删除表 L 的第 i个数据元素:\n");
scanf_s("%d", &j);
Delete(L, j - 1);
DispList(L);
return OK;
}
三、实验结果与分析。
实验四
- 实验目的。
实现在单链表中删除相同的多余结点的程序。
- 相关理论
单链表的遍历,单链表的定位与删除。
- 关键代码。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define LEN 10
typedef int Elemtype;
typedef struct LNode {
Elemtype data;
struct LNode* next;
}LNode, * Linklist;
void Init_Linklist(Linklist* L)
{
*L = (Linklist)malloc(sizeof(LNode));
assert(*L != NULL);
(*L)->next = NULL;
}
void Create_Linklist(Linklist* L)
{
LNode* p, * q;
p = *L;
for (int i = 0; i < LEN; i++)
{
q = (Linklist)malloc(sizeof(LNode));
assert(q != NULL);
scanf_s("%d", &q->data);
p->next = q;
p = q;
}
p->next = NULL;
}
void DeleteSame(Linklist* L)
{
LNode* p, * q, * s;
p = (*L)->next;
for (p; p != NULL; p = p->next)
{
s = p;
for (q = p->next; q != NULL;)
{
if (q->data == p->data)
{
s->next = q->next;
free(q);
q = s->next;
}
else
{
s = q;
q = q->next;
}
}
}
}
void Print_Linklist(Linklist* L)
{
LNode* p;
p = *L;
while (p->next)
{
p = p->next;
printf("%d ", p->data);
}
printf("\n");
}
int main()
{
Linklist L;
Init_Linklist(&L);
Create_Linklist(&L);
printf("初始化链表为:\n");
Print_Linklist(&L);
DeleteSame(&L);
printf("删除后链表为:\n");
Print_Linklist(&L);
return 0;
}
- 实验结果与分析。
实验五
- 实验目的。
给定一颗二叉树用链表表示,用非递归算法求出二叉树叶子节点的数目。
- 相关理论
二叉树的遍历;叶子节点的定义与查找;二叉树的初始化和输入;
- 关键代码。
#include <iostream>
#include <stack>
#include <string>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 1000
typedef struct BiTNode
{
char data;
struct BiTNode* lchild;
struct BiTNode* rchild;
}BiTNode, * BiTree;
using namespace std;
void Initial(BiTree& T) {
T = new BiTNode;
T = NULL;
}
void CreateBiTree(BiTree& T)
{
stack<BiTNode*> s;
BiTNode* p = NULL;
int i = 0;
bool child_Direct;
string TreeStr;
cin >> TreeStr;
while (TreeStr[i] != '\0') {
switch (TreeStr[i])
{
case'(':
s.push(p);
child_Direct = false;
break;
case')':
s.pop();
case',':
child_Direct = true;
break;
default:
p = new BiTNode;
p->data = TreeStr[i];
p->lchild = p->rchild = NULL;
if (T == NULL)
T = p;
else {
if (!child_Direct)
s.top()->lchild = p;
else
s.top()->rchild = p;
}
break;
}
i++;
}
}
void DispBTNode(BiTNode*& b)
{
if (b != NULL)
{
cout << b->data;
if (b->lchild != NULL || b->rchild != NULL)
{
cout << "(";
DispBTNode(b->lchild);
if (b->rchild != NULL) cout << (",");
DispBTNode(b->rchild);
cout << ")";
}
}
}
int Count_BiTree0(BiTree T)
{
int top = -1;
int count = 0;
BiTree S[MaxSize];
while (T != NULL || top != -1)
{
while (T != NULL)
{
if (T->lchild == NULL && T->rchild == NULL)
{
count++;
}
S[++top] = T;
T = T->lchild;
}
if (top != -1)
{
T = S[top--];
T = T->rchild;
}
}
return count;
}
int main()
{
BiTree T;
Initial(T);
CreateBiTree(T);
printf("叶子节点数目:%d\n", Count_BiTree0(T));
return 0;
}
- 实验结果与分析。
实验六
- 实验目的
给定一颗二叉树用链表表示,用非递归算法求出二叉树的深度。
- 相关理论
二叉树的定义与初始化;二叉树的遍历;
- 关键代码
#include <iostream>
#include <stack>
#include <string>
#include<queue>
#define Maxsize 1000;
using namespace std;
typedef struct BiTNode {
char data;
struct BiTNode* lchild, * rchild;
}*BiTree;
void Initial(BiTree& T) {
T = new BiTNode;
T = NULL;
}
void CreateBiTree(BiTree& T)
{
stack<BiTNode*> s;
BiTNode* p = NULL;
int i = 0;
bool child_Direct;
string TreeStr;
cin >> TreeStr;
while (TreeStr[i] != '\0') {
switch (TreeStr[i])
{
case'(':
s.push(p);
child_Direct = false;
break;
case')':
s.pop();
case',':
child_Direct = true;
break;
default:
p = new BiTNode;
p->data = TreeStr[i];
p->lchild = p->rchild = NULL;
if (T == NULL)
T = p;
else {
if (!child_Direct)
s.top()->lchild = p;
else
s.top()->rchild = p;
}
break;
}
i++;
}
}
void DispBTNode(BiTNode*& b)
{
if (b != NULL)
{
cout << b->data;
if (b->lchild != NULL || b->rchild != NULL)
{
cout << "(";
DispBTNode(b->lchild);
if (b->rchild != NULL) cout << (",");
DispBTNode(b->rchild);
cout << ")";
}
}
}
int depth(BiTNode* pRoot) {
if (!pRoot) {
return 0;
}
queue<BiTNode*> q;
q.push(pRoot);
int level = 0;
while (!q.empty()) {
int len = q.size();
level++;
while (len--) {
BiTNode* top = q.front();
q.pop();
if (top->lchild) {
q.push(top->lchild);
}
if (top->rchild) {
q.push(top->rchild);
}
}
}
return level;
}
int main()
{
cout << "请输入树:";
BiTree b;
Initial(b);
CreateBiTree(b);
cout << "深度为:" << depth(b);
}
- 实验结果与分析
实验七
- 实验目的。
给定一颗二叉树用链表表示,用非递归算法求出二叉树结点的数目。
- 相关理论
二叉树的定义、初始化、遍历;
- 关键代码。
#include <iostream>
#include <stack>
#include <string>
#include<queue>
#define Maxsize 1000;
using namespace std;
typedef struct BiTNode {
char data;
struct BiTNode* lchild, * rchild;
}*BiTree;
void Initial(BiTree& T) {
T = new BiTNode;
T = NULL;
}
void CreateBiTree(BiTree& T)
{
stack<BiTNode*> s;
BiTNode* p = NULL;
int i = 0;
bool child_Direct;
string TreeStr;
cin >> TreeStr;
while (TreeStr[i] != '\0') {
switch (TreeStr[i])
{
case'(':
s.push(p);
child_Direct = false;
break;
case')':
s.pop();
case',':
child_Direct = true;
break;
default:
p = new BiTNode;
p->data = TreeStr[i];
p->lchild = p->rchild = NULL;
if (T == NULL)
T = p;
else {
if (!child_Direct)
s.top()->lchild = p;
else
s.top()->rchild = p;
}
break;
}
i++;
}
}
void DispBTNode(BiTNode*& b)
{
if (b != NULL)
{
cout << b->data;
if (b->lchild != NULL || b->rchild != NULL)
{
cout << "(";
DispBTNode(b->lchild);
if (b->rchild != NULL) cout << (",");
DispBTNode(b->rchild);
cout << ")";
}
}
}
int preorder_get_nodes_number(BiTNode* b)
{
if (b == NULL)
return 0;
int num = 0;
stack <BiTNode*> st;
while (b != NULL || !st.empty())
{
while (b != NULL)
{
cout << "节点:" << b->data << endl;
++num;
st.push(b);
b = b->lchild;
}
if (!st.empty())
{
b = st.top();
st.pop();
b = b->rchild;
}
}
return num;
}
int main()
{
cout << "请输入树:";
BiTree b;
Initial(b);
CreateBiTree(b);
cout << "结点数为:" << preorder_get_nodes_number(b);
}
- 实验结果与分析。
实验八
- 实验目的。
写出在无头结点的单链表的第i个元素之前插入一个元素的程序。
- 相关理论
无头结点单链表的遍历、定位、插入;
- 关键代码。
#include<stdio.h>
#include<malloc.h>
#include <stdlib.h>
#define error -1;
#define OK 1;
typedef int ElemType;
typedef int status;
typedef struct LNode
{
ElemType data;
struct LNode* next;
}LNode, * LinkList;
LinkList creat()
{
LinkList L;
L = (LinkList)malloc(sizeof(LNode));
if(!L) printf("memory malloc error!\n");
LinkList p = L;
ElemType a;
int len;
printf("请输入待建表的表长:");
scanf_s("%d", &len);
if (len > 1)
{
printf("请输入第1个元素的值:");
scanf_s("%d", &a);
L = (LinkList)malloc(sizeof(LNode));
if (!L)
printf("memory malloc error!\n");
L->data = a;
LinkList p = L;
for (int i = 1; i < len; i++)
{
printf("请输入第%d个元素的值:", i + 1);
scanf_s("%d", &a);
p->next = (LinkList)malloc(sizeof(LNode));
p->next->data = a;
p = p->next;
}
p->next = NULL;
return L;
}
}
void print(LinkList L)
{
LinkList p = L;
while (p != NULL)
{
printf("%d\n", p->data);
p = p->next;
}
}
status insert(LinkList* L, int i, int b)
{
LinkList p = NULL;
if (i < 1) return error;
if (i == 1)
{
p = (LinkList)malloc(sizeof(LNode));
if (!p)
printf("memory malloc error!\n");
p->data = b;
p->next = *L;
*L = p;
return OK;
}
else
{
p = (LinkList)malloc(sizeof(LNode));
if (!p)
printf("memory malloc error!\n");
p->data = b;
LinkList q = *L;
LinkList qpre = NULL;
while (i > 1)
{
qpre = q;
q = q->next;
i--;
}
p->next = q;
qpre->next = p;
return OK;
}
}
int main()
{
LinkList L = creat();
int i;
printf("请输入待插入的位置:");
scanf_s("%d", &i);
int b;
printf("请输入待插入的元素值:");
scanf_s("%d", &b);
insert(&L, i, b);
print(L);
return 0;
}
- 实验结果与分析。
实验九
- 实验目的
试写一个判别表达式中开、闭括号是否配对出现的程序
- 相关理论
栈的定义和初始化;括号入栈出栈的条件;
- 关键代码
#include<stdio.h>
#define true 1
#define false 0
#define maxsize 100
typedef int status;
status match(char exp[], int n)
{
if (n < 0)
{
printf("匹配失败!");
return false;
}
char stack[maxsize]; int top = -1;
for (int i = 0; i < n; i++)
{
if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
stack[++top] = exp[i];
else if (exp[i] == ')')
{
if (stack[top] == '(')
top--;
else
{
printf("匹配失败!");
return false;
}
}
else if (exp[i] == '}')
{
if (stack[top] == '{')
top--;
else
{
printf("匹配失败!");
return false;
}
}
else if (exp[i] == ']')
{
if (stack[top] == '[')
top--;
else
{
printf("匹配失败!");
return false;
}
}
}
if (top == -1)
{
printf("匹配成功!");
return true;
}
else
{
printf("匹配失败!");
return false;
}
}
void main()
{
char exp[maxsize];
int n, i, x;
printf("请输入表达式的长度n:\n");
scanf_s("%d", &n);
getchar();
if (n > 0)
{
printf("请逐个输入表达式中的字符:\n");
for (i = 0; i < n; i++)
{
x = getchar();
exp[i] = x;
printf("exp[%d]=%c\n", i, exp[i]);
}
}
match(exp, n);
}
- 实验结果和分析
实验十
- 实验目的
编写从串s删除所有与串t中相同字符串的函数
- 相关理论
串的定义和初始化;串的匹配。
- 关键代码
#include<iostream>
#include<string>
using namespace std;
void move(string* S, int location)
{
int length_S = S->length();
for (int i = location; i < length_S; i++)
{
(*S)[i] = (*S)[i + 1];
}
}
void compare(string* S, string t) {
int length_S = S->length();
int length_t = t.length();
int index = 0;
for (int i = 0; i < length_S; i++) {
for (int j = 0; j < length_t; j++) {
if ((*S)[i] == t[j]) {
move(S, i);
}
else {
index++;
}
}
}
if (index == length_t * length_S) {
cout << endl;
cout << "未在主串S中找到需要删除的字符!" << endl;
}
}
void print(string S)
{
cout << endl;
cout << "进行删除操作后,字符串S变为:";
cout << S << endl;
}
int main()
{
cout << "输入字符串S:";
string S;
cin >> S;
cout << "输入需要删除的字符串t:";
string t;
cin >> t;
compare(&S, t);
print(S);
return 0;
}
- 实验结果与分析