实 验 报 告实验课程数据结构
实验项目实验三互联网域名查询
专 业计算机科学与技术班 级
指导教师
目 录
一、 问题定义及需求分析
1问题描述
2实验任务
3需求分析
二、概要设计
(1)抽象数据类型定义
(2)主程序流程
(3)模块关系
三、详细设计
(1)数据类型及存储结构
(2)模块设计
四、调试分析
(1)调试分析
(2)算法时空分析
(3)经验体会
五、使用说明
(1)程序使用说明
六、测试结果
(1)运行测试结果截图
七、附录
(1)源代码
一、 问题定义及需求分析
1实验目的
互联网域名查询
互联网域名系统是一个典型的树形层次结构。从根节点往下的第一层是顶层域如cn、 com等最底层第四层是叶子结点如www等。因此域名搜索可以看成是树的遍历问题。
2实验任务
设计搜索互联网域名的程序。
3需求分析
1)采用树的孩子兄弟链表等存储结构。
2)创建树形结构。
3)通过深度优先遍历搜索。
4)通过层次优先遍历搜索。
二、概要设计
采用孩子兄弟链表存储结构完成二叉树的创建
主程序流程
创建根节点 域名输入 域名拆分 根据孩子兄弟链表表示的树进行插入 调用层次优先遍历 输出遍历结果 调用深度优先遍历 输出遍历结果 结束程序
模块关系
深度优先遍历输出结果
三、详细设计
孩子兄弟链表结构typedef struct CSNode{
ElemType data[10] ;struct CSNode *f irstchild, *nextsibling;
}*CSTree;
模块一深度优先遍历
算法如下void DFS(CSNode *root) {if ( !root) return;//递归结束条件printf("%s\n", root->data) ;
DFS(root->firstchild) ;//递归遍历孩子节点
DFS(root->nextsibling) ;//递归遍历兄弟节点
}
模块二层次优先遍历
算法如下void BFS(CSNode *root) {printf("层次优先搜索遍历结果为 \n") ;
Queue que;que.Clear() ;que.push(root) ;//根节点入队列while ( !que.empty() ) {//队列不空的时候执行循环
CSNode *xx = que.front() ; //取队首元素qu e.p op() ;//出队列printf("%s\n", xx->data) ;if (xx->nextsibling) {//出队节点的孩子节点若不空则入队列que.push(xx->nextsibling) ;
}if (xx->firstchild) {//同样若孩子节点不空则入队列que.push(xx->firstchild) ;
}
}
}
四、调试分析
问题解决
在编写层次优先遍历算法的时候遍历结果总是不正确原因是取完队首元素后没有将出队列经过改正在取队首元素后加上出队列函数将队首元素出队这样便解决了问题
时空分析经过孩子兄弟链表表示的树创建后便得到一棵二叉树对于两个遍历函数深度优先遍历是递归算法在时间上递归算法效率较低尤其是运算次数较大的时候层次优先遍历函数借助到队列所以在内存占用上较多而深度优先遍历算法的空间占用上更优于层次优先遍历
经验体会
孩子兄弟链表表示的树与二叉树可以相互转化它的深度优先遍历递归算法虽较为简单但相比非递归算法而言效率不高。
五、使用说明
第一步输入域名
第二步完成创建
可编辑第三步输出层次优先遍历结果
第四步输出深度有限遍历结果
六、测试截屏
七、附录
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#def ine ElemType char
#define QueueSize 50
#def ine push Push
#def ine empty Empty
#define pop Pop
#def ine front Front typedef struct CSNode{
ElemType data[10] ;struct CSNode *f irstchild, *nextsibling;}*CSTree;//节点结构void InitTree(CSNode *A)
{ //构造一个空树
A = (CSTree)malloc(sizeof(CSNode)) ;
A->f irstchild = A->nextsibling =NULL;
}int Search_(CSNode *X, char *a)
{ //查找待插入的节点在树中是否存在
CSNo de *B;
B = X;//B指向根节点while (B->data)
{if (strcmp(B->data, a) == 0)
{
X = B; //若存在相等的则返回1return 1;
}else
{
B = B->nextsibling; //否则B指向它的兄弟节点
}
}return 0;
}void hanshu1(CSNode *A, ElemType *s)
{//将节点插入到树中
CSNo de *B, *X;char *s tr;int i;
X = A; //X指向根节点
B = (CSTree)malloc(sizeof(CSNode)) ;
B->f irstchild = B->nextsibling =NULL;c har ZhongZhuan[15] ; //中转数组f or (; s != ' \0' ;)
{
//zhongzhuan接受s中xxx.部分或取完翻转zhongzhuan str = strchr(s, ' . ' ) ;//返回字符串s中第一次出现点的位置if (str)
{i = str - s;
ZhongZhuan[i + 1] = '\0' ;f or (; i >= 0; i--, s++)
{
ZhongZhuan[i] = s[0] ;//将拆分后的节点传入中转数组中}
}
可编辑else
{//字符串中不含点符号
_strrev(s) ;i = strlen(s) ;
ZhongZhuan[i + 1] = '\0' ;f or (; i >= 0; i--)
{
ZhongZhuan[i] = s[i] ;//将字符串存入中转数组里
}i f (Search_(X, ZhongZhuan))
{//若要插入的字符串已存在该层面上
X = X->firstchild;//x指向孩子节点cont inue;
}i f (X->data[0] == '0' )
{s trcpy(X->data, ZhongZhuan) ;//将中转数组的信息复制给待插入节点B = (CSTree)malloc(sizeof(CSNode)) ;
B->f irstchild = B->nextsibling =NULL;
}else
{if (X->firstchild)
{strcpy(B->data, ZhongZhuan) ;
X->nextsibling = B;//将作为的兄弟节点
B = (CSTree)malloc(sizeof(CSNode)) ;
B->f irstchild = B->nextsibling =NULL;
X = X->nextsibling; //x指向它的兄弟节点
}else
{strcpy(B->data, ZhongZhuan) ;
X->firstchild = B;
B = (CSTree)malloc(sizeof(CSNode)) ;
B->f irstchild = B->nextsibling =NULL;
X = X->firstchild;
}
}
}
}
可编辑struct Queue {int Top, Tail ;
CSNo de *a[1000] ;void Clear() ;void Push(CSNode *e) ;void Pop() ;
CSNode *Front() ;bool Empty() ;
} ;//队列封装为结构体void Queue: :Clear() {
Top = Tail = 0;return;
}//清空队列void Queue: :Push(CSNode *e) {a[Ta i l++] = e;return;
}//入队列void Queue: :Pop() {
Top++;return;
}//出队列
CSNode *Queue: :Front() {return a[Top] ;
}//取队首元素bool Queue: :Empty() {return Top == Tail;
}//判空void BFS(CSNode *root) {printf("层次优先搜索遍历结果为 \n") ;
Queue que;que.Clear() ;que.push(root) ;//根节点入队列while ( !que.empty() ) {//队列不空的时候执行循环
CSNode *xx = que.front() ; //取队首元素qu e.p op() ;//出队列printf("%s\n", xx->data) ;if (xx->nextsibling) {//出队节点的孩子节点若不空则入队列que.push(xx->nextsibling) ;
}if (xx->firstchild) {//同样若孩子节点不空则入队列que.push(xx->firstchild) ;
}
}
}void DFS(CSNode *root) {if ( !root) return;//递归结束条件printf("%s\n", root->data) ;
DFS(root->firstchild) ;//递归遍历孩子节点
DFS(root->nextsibling) ;//递归遍历兄弟节点
}int main()
{int j;
CSNode *A;
A = (CSNode*)mal loc(si zeof(CSNode) ) ;//根节点创建A->f irstchild = A->nextsibling =NULL;
A->data[0] = '0' ;char b[30] ; //定义字符数组接收域名c har *s;f or (j = 0; j<3; j++)
{printf("请输入网址 ") ;gets(b) ;s = b;//s指向数组b
_strrev(s) ;h an s hu 1 (A, s) ;//字符串s存入A中
}
BFS(A) ;//层次优先遍历printf("深度优先遍历结果为:\n") ;
DFS(A) ;//深度优先遍历
}
. .
易探云服务器怎么过户/转让?易探云支持云服务器PUSH功能,该功能可将云服务器过户给指定用户。可带价PUSH,收到PUSH请求的用户在接收云服务器的同时,系统会扣除接收方的款项,同时扣除相关手续费,然后将款项打到发送方的账户下。易探云“PUSH服务器”的这一功能,可以让用户将闲置云服务器转让给更多需要购买的用户!易探云服务器怎么过户/PUSH?1.PUSH双方必须为认证用户:2.买家未接收前,卖家...
这两天Linode发布了十八周年的博文和邮件,回顾了过去取得的成绩和对未来的展望。作为一家运营18年的VPS主机商,Linode无疑是有一些可取之处的,商家提供基于KVM架构的VPS主机,支持随时删除(按小时计费),可选包括美国、英国、新加坡、日本、印度、加拿大、德国等全球十多个数据中心,所有机器提供高出入网带宽,最低仅$5/月($0.0075/小时)。This month marks Linod...
? ? ? ?创梦网络怎么样,创梦网络公司位于四川省达州市,属于四川本地企业,资质齐全,IDC/ISP均有,从创梦网络这边租的服务器均可以****,属于一手资源,高防机柜、大带宽、高防IP业务,另外创梦网络近期还会上线四川联通大带宽,四川联通高防IP,一手整CIP段,四川电信,联通高防机柜,CN2专线相关业务。成都优化线路,机柜租用、服务器云服务器租用,适合建站做游戏,不须要在套CDN,全国访问快...