数据结构上机指导
第一章 绪论
1.1求素数
#include <stdio.h>
#include <math.h>
#include <stdio.h>
#include <windows.h>
bool prime(int n)
{
int i;
for (i = 2; i <= (int)sqrt(n); i++)
if (n % i == 0)
return false;
return true;
}
//sqrt 开平方根
void main()
{
int n, i, j = 0;
printf("n:");
scanf_s("%d", &n);
//scanf 格式化输入
//scanf ("<格式化字符串>",<地址表>);
//&n 获取n的地址
printf("小于等于%d的素数:\n", n);
if (n > 2)
{
printf("%4d", 2);
j++;
}
for(i = 3; i <= n; i = i+2)
if (prime(i))
{
printf("%4d", i);
//%4d 4位整数 (i前有三个空格 补齐)
if (j != 0 && ++j % 10 == 0)
printf("\n");
}
printf("\n");
system("pause");
}
//时间复杂度O(根号n)
2.2求一个正整数的各位数字之和
#include <stdio.h>
#include <windows.h>
int func(int num)
{
int s = 0;
do
{
s = s + num % 10;//%求余
num = num / 10;// /求商
} while (num);
return(s);
}
void main()
{
int n;
printf("请输入一个整数:");
scanf_s("%d", &n);
printf("各位数字之和:%d\n", func(n));
printf("\n");
system("pause");
}
3.3求一个字符串是否为回文
#include<windows.h>
#include<stdio.h>
#include<string.h>
/*string.h头文件里常用的函数有:
strlen求字符串长度。
strcmp比较2个字符串是否一样。
strcat字符串连接操作。
strcpy字符串拷贝操作。
strncat字符串连接操作(前n个字符)。
strncpy字符串拷贝操作(前n个字符)。
strchr查询字串。
strstr 查询子串。*/
#define MAX 100 //字符串的最大长度是100
bool func(char s[])
{
bool flag = true;
int i, j, slen = strlen(s);//strlen求字符串长度。
for( i = 0, j = slen-1; i < slen -1;i ++ , j--)
if (s[i] != s[j])
{
flag = false;
break;
}
return (flag);
}
void main()
{
char s[MAX];
printf("请输入一个字符串:");
scanf_s("%s", &s); //%s 读入一个字符串
if (func(s))
printf("%s字符串是回文\n", s);
else
printf("%s字符串不是回文\n", s);
}
第二章 线性表
2.1 顺序表的基本操作
//algo2-1.cpp
#include <stdio.h>
#include <malloc.h>
#define MaxSize 50
typedef char ElemType;//typedef 类型申明定义
typedef struct //定义结构体
{
ElemType data[MaxSize];
int length;
}SqList;//SqList为定义的结构体类型,是一个实例
void InitList(SqList *&L) //建立的顺序表指针给L
{
L = (SqList *)malloc(sizeof(SqList));
L->length = 0;
}
void DestroyList(SqList *L)
{
free(L);
}
bool ListEmpty(SqList *L)
{
return (L->length == 0);
}
int ListLength(SqList *L)
{
return (L->length);
}
void DispList(SqList *L)
{
int i;
if (ListEmpty(L))return;
for (i = 0; i < L->length; i++)
printf("%c", L->data[i]);
printf("\n");
}
bool GetElem(SqList *L, int i, ElemType &e)
{
if (i < 1 || i > L->length)
return false;
e = L->data[i - 1];
return true;
}
int LocateElem(SqList *L, ElemType e)
{
int i = 0;
while (i < L->length && L->data[i] != e)
i++;
if (i >= L->length)
return 0;
else
return i + 1;
}
bool ListInsert(SqList *&L, int i, ElemType e)
{
int j;
if (i < 1 || i > L->length + 1)
return false;
i--;
for (j = L->length; j > i; j--)
L->data[j] = L->data[j - 1];
L->data[i] = e;
L->length++;
return true;
}
bool ListDelete(SqList *&L, int i, ElemType &e)
{
int j;
if (i < 1 || i >L->length)
return false;
i--;
e = L->data[i];
for (j = i; j < L->length; j++)
L->data[j] = L->data[j + 1];
L->length--;
return true;
//exp2-1.cpp
#include <stdio.h>
#include <malloc.h>
#include <windows.h>
#define MaxSize 50
typedef char ElemType;
typedef struct
{
ElemType data[MaxSize];
int length;
}SqList;
extern void InitList(SqList *&L);//extern跨文件访问
extern void DestroyList(SqList *&L);
extern bool ListEmpty(SqList *L);
extern bool GetElem(SqList *L, int i, ElemType &e);
extern int ListLength(SqList *L);
extern void DispList(SqList *L);
extern int LocateElem(SqList *L, ElemType e);
extern bool ListInsert(SqList *&L, int i, ElemType e);
extern bool ListDelete(SqList *&L, int i, ElemType &e);
void main()
{
SqList *L;
ElemType e;
printf("顺序表的基本运算如下:\n");
printf("(1)初始化顺序表L \n");
InitList(L);
printf("(2)依次采用尾插法插入a,b,c,d,e元素\n");
ListInsert(L, 1, 'a');
ListInsert(L, 2, 'b');
ListInsert(L, 3, 'c');
ListInsert(L, 4, 'd');
ListInsert(L, 5, 'e');
printf("(3)输出顺序表L:");
DispList(L);
printf("(4)顺序表的长度 - %d\n", ListLength(L));
printf("(5)顺序表L为% s\n");
GetElem(L, 3, e);
printf("(6)顺序表L的第三个元素 = %c\n", e);
printf("(7)元素a的位置= %d \n", LocateElem(L, 'a'));
printf("(8)在第4个元素位置上插入f元素\n");
ListInsert(L, 4, 'f');
printf("(9)输出顺序表L:");
DispList(L);
printf("(10)删除L的第三个元素\n");
ListDelete(L, 3, e);
printf("(11)输出顺序表L;");
DispList(L);
printf("(12)释放顺序表L\n");
system("pause");
}
}
2-2单链表的基本操作
//algo2-2.cpp
#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LinkList;
void InitList(LinkList *&L)
{
L = (LinkList *)malloc(sizeof(LinkList));
L->next = NULL;
}
void DestoryList(LinkList *&L)
{
LinkList *p = L, *q = p->next;//p指向头节点,q指向首节点
while (q != NULL)
{
free(p);
p = q;
q = p->next; //pq都往后移动一位
}
free(p);
}
bool ListEnpty(LinkList *L)
{
return (L->next == NULL);
}
int ListLength(LinkList *L)
{
LinkList *p = L; int i = 0;
while (p->next != NULL)
{
i++;
p = p->next;
}
return(i);
}
void DispList(LinkList *L)
{
LinkList *p = L->next;
while (p != NULL)
{
printf("%c", p->data);
p = p->next;
}
printf("\n");
}
bool GetElem(LinkList *L, int i, ElemType &e)
{
int j = 0;
LinkList *p = L;
while (j < i && p != NULL)
{
j++;
p = p->next;
}
if (p == NULL)
return false;
else
{
e = p->data;
return true;
}
}
int LocateaElem(LinkList *L, ElemType e)
{
int i = 1;
LinkList *p = L->next;
while (p!= NULL&&p -> data!=e)
{
p = p->next;
i++;
}
if (p == NULL)
return false;
else
{
e = p->data;
return true;
}
}
int LocateElem(LinkList *L, ElemType e)
{
int i = 1;
LinkList *p = L->next;
while (p != NULL&&p->data!= e)
{
p = p->next;
i++;
}
if (p == NULL)
return(0);
else
return(i);
}
bool ListInsert(LinkList *&L, int i, ElemType e)
{
int j = 0;
LinkList *p = L, *s;
while (j < i - 1 && p!= NULL)
{
j++;
p = p->next;
}
if (p == NULL)
return false;
else
{
s = (LinkList *)malloc(sizeof(LinkList));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
}
bool ListDelete(LinkList *&L, int i, ElemType &e)
{
int j = 0;
LinkList *p = L, *q;
while (j < i - 1 && p != NULL)
{
j++;
p = p->next;
}
if (p == NULL)
return false;
else
{
q = p->next;
p->next = q->next;
free(q);
return true;
}
}
//exp2-2.cpp
#include <stdio.h>
#include <malloc.h>
#include <Windows.h>
typedef char ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LinkList;
extern void InitList(LinkList *&L);
extern void DestroyList(LinkList *&L);
extern bool ListEmpty(LinkList *L);
extern int ListLength(LinkList *L);
extern void DispList(LinkList *L);
extern bool GetElem(LinkList *L, int i, ElemType &e);
extern int LocateElem(LinkList *L, ElemType e);
extern int LocateElem(LinkList *L, ElemType e);
extern bool ListInsert(LinkList *&L, ElemType e);
extern bool ListInsert(LinkList *&L, int i, ElemType e);
extern bool ListDelete(LinkList *&L, int i, ElemType &e);
void main()
{
LinkList *h;
ElemType e;
printf("单链表的基本运算如下:\n");
printf("(1)初始化但俩表h\n");
InitList(h);
printf("(2)依次采用尾插法插入a,b,c,d,e元素\n");
ListInsert(h, 1, 'a');
ListInsert(h, 2, 'b');
ListInsert(h, 3, 'c');
ListInsert(h, 4, 'd');
ListInsert(h, 5, 'e');
printf("(3)输出单链表h:");
DispList(h);
printf("(4)单链表h的长度= %d\n", ListLength(h));
printf("(5)单链表h为5s\n");
GetElem(h, 3, e);
printf("(6)单链表h的第三个元素 = % c\n", e);
printf("(7)元素a的位置=%d\n", LocateElem(h, 'a'));
printf("(8)在第四个元素的位置上插入元素f\n");
ListInsert(h, 4, 'f');
printf("(9)输出点链表h:");
DispList(h);
printf("(10)删除h的第三个元素\n");
ListDelete(h, 3, e);
printf("(11)输出单链表h:");
DispList(h);
printf("(12)释放单链表h\n");
system("pause");
}
3-1栈基本
//algo.cpp
#include<stdio.h>
#include<malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct
{
ElemType data[MaxSize];
int top; //定义栈顶指针
}SqStack;
void InitStack(SqStack *&s)//初始化栈
{
s = (SqStack *)malloc(sizeof(SqStack));
s->top = -1;//栈顶指针设置为-1
}
void DestroyStack(SqStack *&s)//销毁栈s
{
free(s);
}
/*
void initstack1(int *s){ *s=8 ;}
void initstack2(int &*s){ *s=8;}
//这两个函数分为函数1和函数2来表示,另外sqstack是数据结构中的类C语言,在编译中是会报错的,我们换一个数据类型
int main(){
int a=1,b=1;
int *p1=&a,*p2=&b;//不好意思第一次搞错了
initstack1(p1);
cout<<*p1; //结果是输出1
initstack2(p2);
cout<<*p2; //结果是输出8
}
引用(加&)和非引用(不加&)为什么结果不一样呢,都是赋值的函数呀
这就是函数作用域和生命期的原因
不加引用是把实参复制一份给形参,形参的变化不影响实参,
而非引用是直接对实参进行操作,也就是赋予了函数2异地操作数据的能力*/
bool StackEmpty(SqStack *s)//判断栈为空
{
return (s->top == -1);
}
bool Push(SqStack *&s, ElemType e)//进栈
{
if (s->top == MaxSize - 1)//栈满
return false;
s->top++; //上溢出
s->data[s->top] = e;
return true;
}
bool Pop(SqStack *&s, ElemType &e)//出栈
{
if (s->top == -1)//栈为空的情况,栈下溢出
return false;
e = s->data[s->top];
s->top--;
return true;
}
bool GetTop(SqStack *s, ElemType &e)//取栈顶元素
{
if (s->top == -1)//空栈 下溢出
return false;
e = s->data[s->top];//取栈顶元素
return true;
}
//exp3-1.cpp
#include<windows.h>
#include<stdio.h>
#include<malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct
{
ElemType data[MaxSize];
int top;
}SqStack;
extern void InitStack(SqStack *&s);
extern void DestroyStack(SqStack *&s);
extern bool StackEmpty(SqStack *s);
extern bool Push(SqStack *&s, ElemType e);
extern bool Pop(SqStack *&s, ElemType &e);
extern bool GetTop(SqStack *s, ElemType &e);
void main()
{
ElemType e;
SqStack *s;
printf("栈s的基本运算\n");
printf("(1)初始化栈s\n");
InitStack(s);
printf("(2)栈为");
if (StackEmpty(s) ==true)
printf("空");
else
printf("非空");
printf("\n");
printf("(3)依次进栈元素a,b,c,d,e\n");
Push(s, 'a');
Push(s, 'b');
Push(s, 'c');
Push(s, 'd');
Push(s, 'e');
printf("(4)栈为");
if (StackEmpty(s) == true)
printf("空");
else
printf("非空");
printf("\n");
printf("(5)出栈序列:");
/* while (s->top!=-1);
{
Pop(s, e);
printf("%c", e);
}*/
do {
Pop(s, e);
printf("%c", e);
} while (s->top != -1);
printf("\n");
printf("(6)栈为");
if (StackEmpty(s) == true)
printf("空");
else
printf("非空");
printf("\n");
printf("(7)释放栈\n");
DestroyStack(s);
system("pause");
}
//sizeof 一元运算符 计算变量占内存空间的大小
//(1.增加程序可移植 2.不会导致额外的运算时间)
//sizeof(类型) sizeof(变量或表达式)
//宏定义
//#define 标识符 字符串
// # 编译预处理指令 :在源程序编译之前,先对程序中的编译预处理指令进行处理
//然后将处理的结果和源程序一起进行编译 #define pi 3.14159(不加;)
//预编译时,会将所有的宏名全部替换为字符串
7-1二叉树的基本操作
//algo.cpp
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
//typedef 行为有点像 #define 宏,用其实际类型替代同义字。
//不同点是 typedef 在编译时被解释,因此让编译器来应
//付超越预处理器能力的文本替换。
typedef struct node
{
ElemType data;
struct node *lchild;
struct node *rchild;
}BTNode;
void CreateBTNode(BTNode *&b, char *str)//由str串创建二叉链
//b为创建的二叉链的根节点指针
//
{
BTNode *St[MaxSize], *p = NULL;//st数组作为顺序栈
int top = -1, k, j = 0; // top为栈顶指针
char ch; //
b = NULL; //初始时二叉链为空
ch = str[j];
while (ch != '\0') // 循环扫描str中的每个字符
{
switch (ch)
{
case'(':top++; St[top] = p; k = 1; break;//处理左孩子节点
case')':top--; break; //栈顶节点的子数创建完毕
case',': k = 2; break;//开始处理右孩子节点
default:
p = (BTNode *)malloc(sizeof(BTNode));//p指向一个新创建的节点
p->data = ch;
p->lchild = p->rchild = NULL;
if (b == NULL) //若尚未创建根节点
b = p; //p就指定为根节点
else//若已经创建根节点
{
switch (k)
{
case 1:St[top]->lchild = p;
break;//新创建的结点作为栈顶节点的左孩子
case 2:St[top]->rchild = p;
break;
}
}
}//继续扫描str
j++;
ch = str[j];
}
}
BTNode *FindNode(BTNode *b, ElemType x)//返回data域为x的节点指针
{
BTNode *p;
if (b == NULL)
return NULL;
else if (b->data == x)
return b;
else
{
p = FindNode(b->lchild, x);//根节点没有开始查找左节点
if (p != NULL)
return b;
else
return FindNode(b->rchild, x);//开始查找右节点
}
}
BTNode * lchildNode(BTNode *p)//返回*p节点的左孩子节点指针
{
return p->lchild;
}
BTNode * rchildNode(BTNode *p)
{
return p->rchild;
}
int BTNodeDepth(BTNode *b)//求二叉树的深度
{
int lchilddep, rchilddep;
if (b == NULL)
return (0);
else
{
lchilddep = BTNodeDepth(b->lchild);//作子数的高度为lchilddep
rchilddep = BTNodeDepth(b->rchild);//
return
(lchilddep > rchilddep) ? (lchilddep + 1) : (rchilddep + 1);
}
}
void DispBTNode(BTNode *b)//括号表示发输出二叉树
{
if (b!= NULL)
{
printf("%c", b->data);
if (b->lchild != NULL || b->rchild!= NULL)
{
printf("(");//有孩子节点时输出这个
DispBTNode(b->lchild);//递归处理左子树
if (b->rchild != NULL)
printf(",");//有右孩子才输出,
DispBTNode(b->rchild);
printf(")");//有孩子节点输出)
}
}
}
int BTWith(BTNode * b)//求二叉树的宽度
{
struct
{
int lno; //节点的层次编号
BTNode *p; // 节点指针
}Qu[MaxSize];//定义顺寻非循环队列
int front, rear;
int lnum, max, i, n;//定义队尾和队首指针
front = rear = 0;//队列为空
if (b != NULL)
{
rear++;
Qu[rear].p = b;//根节点指针入队
Qu[rear].lno = 1;//根节点的层次编号为1
while (rear != front)//队列不为空
{
front++;
b = Qu[front].p;//队头出列
lnum = Qu[front].lno;
if (b->lchild != NULL)//左孩子入列
{
rear++;
Qu[rear].p = b->lchild;
Qu[rear].lno = lnum + 1;
}
if (b->rchild != NULL)
{
rear++;
Qu[rear].p = b->rchild;
Qu[rear].lno = lnum + 1;
}
}
max = 0; lnum = 1; i = 1;
while (i <= rear)
{
n = 0;
while (i <=rear&&Qu[i].lno == lnum)
{
n++;
i++;
}
lnum = Qu[i].lno;
if (n > max)max = n;
}
return max;
}
else
return 0;
}
int Nodes(BTNode *b)
{
int num1, num2;
if (b == NULL)
return 0;
else if (b->lchild == b->rchild == NULL)
return 1;
else
{
num1 = Nodes(b->lchild);
num2 = Nodes(b->rchild);
return (num1 + num2 + 1);
}
}
int LeafNodes(BTNode *b)//求b 的节点个数
{
int num1, num2;
if (b == NULL)
return 0;
else if(b->lchild == NULL&&b->rchild == NULL)
return 1;
else
{
num1 = LeafNodes(b->lchild);
num2 = LeafNodes(b->rchild);
return(num1 + num2 + 1);
}
}
void DestroyBTNode(BTNode *&b)
{
if (b != NULL)
{
DestroyBTNode(b->lchild);
DestroyBTNode(b->rchild);
free(b);
}
}
//expj7-1.cpp
#include<windows.h>
#include<stdio.h>
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node *lchild;
struct node *rchild;
}BTNode;
extern void CreateBTNode(BTNode *&b, char *str);
extern BTNode* FindNode(BTNode *b, ElemType x);
extern BTNode* lchildNode(BTNode *p);
extern BTNode * rchildNode(BTNode * p);
extern int BTNodeDepth(BTNode *b);
extern void DispBTNode(BTNode *b);
extern int BTWith(BTNode *b);
extern int Nodes(BTNode *b);
extern int LeafNodes(BTNode *b);
extern void DestroyBTNode(BTNode *&b);
void main()
{
BTNode *b, *p, *lp, *rp;;
CreateBTNode( b, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
printf("二叉树的基本运算如下:\n");
printf("(1)输出二叉树:");
DispBTNode(b);
printf("\n");
printf("(2)H节点");
p = FindNode(b, 'H');
if (p != NULL)
{
lp = lchildNode(p);
if (p != NULL)
printf("左孩子为%c", lp->data);
else
printf("无左孩子");
rp = rchildNode(p);
if (p != NULL)
printf("右孩子为%c", rp->data);
else
printf("无右孩子");
}
printf("\n");
printf("(3)二叉树b的深度:%d\n", BTNodeDepth(b));
printf("(4)二叉树b的宽度:%d\n", BTWith(b));
printf("(5)二叉树b的节点个数为:%d\n", Nodes(b));
printf("(6)二叉树b的叶子节点个数为:%d\n", LeafNodes(b));
printf("(7)释放二叉树");
DestroyBTNode(b);
system("pause");
}