(1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel) Node * ReverseList(Node *head) //链表逆序 |
Link Reverse(Link Head)
{Link Pointer;
Link Back;
Link Next;
Back = Head;
Pinter = Back->next;
Back->next = NULL;
Next = Pointer->next;
Pointer->next = Back;
Back = Pointer;
Pointer = Next;
while (Pointer->next !=NULL)
{Next = Pointer->next;
Pointer->next = Back;
Back = Pointer;
Pointer = Next;
}
Pointer->next = Back;
Head = Pointer;
return Head;
}
排序方法:冒泡排序,快速排序,选择排序。
冒泡排序:if (左边的值>右边的值)then 此两个值的位置互换。
else 此两个值的位置不变。
右边的值继续和下一个值比较。
void bubbleSort(int *list,int index)
{int i, j,ttemp;
while (1)
{for (j=index;j>0;j--)
{
for(i=0;i<j-1;i++)
{if(list [i]>list[i+1])
{temp=list[i+1];
list[i+1]=list[i];
list[i]=temp;
}
}
}
}
}
查找:线性查找,折半查找,费氏查找,插补查找。。。。。。
折半查找:intBinary_Search(int Key)
{int left;
int Right;
int Middle;
Left = 0;
Right = Max-1;
while ( Left<=Right)
{Middle =(Left+Right)/2;
if(Key<Data[Middle]) Right=Middle-1;
else if(Key>Data[Middle]) Left = Middle+1;
else if(Key==Data[Middle]) {Printf("Data[%d]=%d\n",Middle,Data[Middle]);return 1;}
//count++;
}
return 0;
}
二叉树的建立与查找:
二叉树表示法:1、二叉树数组表示法2、二叉树结构数组表示法3、二叉树链表表示法
(1) //建立二叉树
void creat_btree(int *b_tree,int*nodelist,int len)// b_tree......nodelist是数组。
{int i;
int level;//树的阶层数
b_tree[1]=nodelist[1];//以第一个元素为根节点
for (i=2;i<=len;i++)//依序建立其它节点
{level = 1;//从阶层1开始建立
while(b_tree[level]!=0)//判断是否有子树存在
{if (nodelist[i] < b_tree[level])//判断是左子树还是右子树
level = level *2;//左子树
else level = level *2 + 1; //右子树
}
b_tree[level] = nodelist[i]; //将元素值存入节点
}
}
void main()
{int i,index;
int data;
int b_tree[16];
int nodelist[16];
printf("\nPlease input the elements ofbinary tree(Exit for 0):\n");
index = 1;
scanf("%d", &data);
while (data!=0)
{nodelist[index] = data;
index = index+1;
scanf("%d",&data);
for (i=1;i<16;i++) b_tree[i] = 0;
create_btree(b_tree,nodelist,index);
1.求下面函数的返回值(微软) int func(x) 假定x = 9999。 答案:8 思路:将x转化为2进制,看含有的1的个数。
|
}
}
(2)structtree{
intleft;
intdata;
intright;
};
typedefstruct tree treenode;
treenodeb_tree[15];
//建立二叉树
void creat_btree(int *b_tree,int*nodelist,int len)
{int i;
int level;//树的阶数
int position;//左树-1,右树1
b_tree[0].data = nodelist[0];//以第一个元素为根节点
for (i = ;i<len;i++)//依序建立其它节点
{b_tree[i].data= nodelist[i];//将元素值存入节点
level = 0;//从树根开始建立
position = 0;//设置position值
while(position== 0)//寻找节点位置
{if (nodelist[i] > b_tree[level].data)//判断是左子树或是右子树
if (b_tree[level].right!= -1)
level = b_tree[level].right;
else position = -1;
else if(b_tree[level]>left!=-1)//左树是否有下一阶层
level = b_tree[level].left;
else position = 1;//设置为左树
}
if (position == 1) b_tree[level].left= i;//建立节点的左右连结 连结左子树
else b_tree[level].right = i;//连结右子树
}
}
(3)structtree{
structtree *left;
intdata;
structtree *right;
}
typedefstruct tree treenode;
treenode*b_tree;
智力题:
SQL语句:
操作对象 |
操作方式 |
||
创建 |
删除 |
修改 |
|
表 |
CREATE TABLE |
DROP TABLE |
ALTER TABLE |
视图 |
CREATE VIEW |
DROP VIEW |
|
索引 |
CREATE INDEX |
DROP INDEX |
|
CREATE TABLE Student (Sno CHAR(5) NOT NULLUNIQUE,
Sname CHAR(20),
Ssex CHAR(1),
Sage INT,
Sdept CHAR(25));
ALTER TABLE<表名>[ADD<新列名><数据类型>[完整性约束]] [DROP<完整性约束名>] [MODIFY<列名><数据类型>];
DROP TABLE <表名>
CREATE [UNIQUE][CLUSTER]INDEX <索引名> ON <表名>(<列名>[<次序>][ , <列名>[<次序>]].......);
聚簇索引:CREATECLUSTER INDEX Stusname ON Student (Sname);
CREATE UNIQUE INDEX SCno ON SC (Sno ASC,CnoDESC);
DROP INDEX <索引名>
CREATE VIEW <视图名>[(<列名>[ , <列名>]...)]
AS <子查询>
[WITH CHECK OPTION];
查询:(单表查询,多表查询)
SELECT [ALL | DISTINCT]<目标列表达式>[ , <目标列表达式>]...
FROM <表名或视图名>[ , <表名或视图名>]...
[WHERE <条件表达式>]
[GROUP BY <列名1>[HAVING<条件表达式>]]
[ORDER BY<列名2>[ASC | DESC]];
“准则”就是指优化策略。“优化”,一般能提高查询效率,但不一定是最优的。“最优化”是一个比较复杂的问题。这里讨论基本的经验的优化策略。
(l)选择运算应尽可能先做。在优化策略中这是最重要、最基本的一条。它常常可使执行时节约几个数量级,因为选择运算一般使计算的中间结果大大变小。
(2)在执行连接前对关系适当地预处理。预处理方法主要有两种,在连接属性上建立索引和对关系排序,然后执行连接。第一种称为索引连接方法,第二种称为排序合并(SORT-MERGE)连接方法
例如STUDENTSC这样的自然连接,用索引连接方法的步骤是:
1) 在SC上建立Sno的索引
2) 对STUDENT中每一个元组,由Sno值通过SC的索引查找相应的SC元组
3) 把这些SC元组和STUDENT元组连接起来.这样Student表和SC表均只要扫描一遍。处理时间只是两个关系大小的线性函数。
用排序合并连接方法的步骤是:
1) 首先对Student表和SC表按连接属性Sno排序(图4.2)
2) 取Student表中第一个Sno,依次扫描SC表中具有相同Sno的元组,把它们连接起来:
3) 当扫描到Sno不相同的第一个SC元组时,返回Student表扫描它的下一个元组,再扫描SC表中具有相同Sno的元组,把它们连接起来。
重复上述步骤直到Student 表扫描完。
这样Student表和SC表也只要扫描一遍。当然,执行时间要加上对两个表的排序时间。即使这样,使用预处理方法执行连接的时间一般仍大大减少。
(3)把投影运算和选择运算同时进行。如有若干投影和选择运算,并且它们都对同一个关系操作,则可以在扫描此关系的同时完戌所有的这些运算以避免重复扫描关系。
4)投影同双目运算结合。把投影同其前或其后的双目运算结合起来,没有必要为了去掉某些字段而扫描一遍关系。
(5)选择同某些笛卡尔积结合起来构成一个连接运算.杷某些选择同在它前面要执行的笛卡尔积结合起来成为一个连接运算,连接特别是等值连接运算要比同样关系上的笛卡尔积省很多时间(如4.2.2中的实例)。
(6)找出公共子表达式。如果重复出现的子表达式的查询结果不是很大的关系,并且从外存中读入这个关系比计算该子表达式的时间少得多,则先计算一次公共子表达式并把结果写入中间文件是合算的。当查询的是视图时,定义视图的表达式就是公共子表达式的情况。
测试用例:
测试方法:(1)黑盒测试:不考虑程序的内部结构和处理过程。测试接口,它只检查程序功能是否能按照规格说明书的规定正常使用,能否接收输入数据并产生正确的输出信息。
(功能测试)(2)白盒测试。与前者相反,看成透明的白盒子,知道程序的结构和处理算法。按程序内部的逻辑测试程序,检测主要执行通路是否按预定要求正确工作。(结构测试)
3、const 有什么用途?(请至少说明两种)(5分)答:(1)可以定义 const 常量(2)const可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 4、在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”? (5分)答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y); 该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
|
特殊函数:
int Strlen(char*s)
{int i;
for(i=0;s[i]!='\0')
{i++; return i;}
}
char *Strcpy(char*s1,char *s2)
{int i;
for(i=0;s2[i]!='\0';i++)
{s1[i]=s2[i];
s1[i]='\0';
return s1;
}
}
char *Strcat(char *s1,char *s2)
{int i,j;
for (i=0;s1[i]!='\0';i++);
for (j=0;s2[j]!='\0';j++)
六、编写类String的构造函数、析构函数和赋值函数(25分)已知类String的原型为:class String{ public: String(const char *str = NULL); // 普通构造函数String(const String &other); // 拷贝构造函数 ~ String(void); // 析构函数 String & operate =(const String &other); // 赋值函数 private:char *m_data; // 用于保存字符串};请编写String的上述4个函数。标准答案:// String的析构函数 String::~String(void) // 3分{delete [] m_data; // 由于m_data是内部数据类型,也可以写成 delete m_data;}// String的普通构造函数 String::String(const char *str) // 6分 {if(str==NULL) { m_data = new char[1]; // 若能加 NULL 判断则更好*m_data = ‘’; } else{int length = strlen(str); m_data = new char[length+1]; // 若能加 NULL 判断则更好 strcpy(m_data, str); } } // 拷贝构造函数String::String(const String &other) // 3分{ int length = strlen(other.m_data); m_data = new char[length+1]; // 若能加 NULL 判断则更好 strcpy(m_data, other.m_data); }// 赋值函数String & String::operate =(const String &other) // 13分{ // (1) 检查自赋值 // 4分if(this == &other)return *this;// (2) 释放原有的内存资源 // 3分delete [] m_data;// (3)分配新的内存资源,并复制内容 // 3分int length = strlen(other.m_data); m_data = new char[length+1]; // 若能加 NULL 判断则更好strcpy(m_data, other.m_data);// (4)返回本对象的引用 // 3分return *this;} |
s1[i+j]='\0';
return s1;
}
}
char *Strrep(char *s1,char *s2,int pos)
{int i,j;
pos--;
i=0;
for (j=pos;s1[j]!='\0';j++)
{if(s2[i]!='\0')
{s1[j]=s2[i];i++;}
else break;
}
return s1;
}
char *strins(char *s1,char *s2,int pos)
{int s1_length;
ints2_length;
inti,j;
pos--;
s1_length=strlen(s1);
s2_length=strlen(s2);
for(i=s1_length;i>=pos;i--)
s1[i+s2_length]=s1[i];
for(j=pos;s2[j-pos]!='\0';j++)
s1[j]=s2[j-pos];
return s1;
}
char *Strdel(char *s,int pos,int len)
{int i;
pos--;
for (i=pos+len;s[i]!='\0',i++)
{s1[i-len]=s1[i];}
s[i-len]='\0';
return s;
}
char Strcmp(char*s1,char *s2)
{int i,j;
for (i=0;s1[i]==s2[i];i++)
if (s1[i]=='\0' && s2[i]=='\0') return 0;
if (s1[i]>s2[i]) return 1;
return -1;
}
网络部分:
TCP/IP:
子网掩网:
网络类别 |
最大网络数 |
第一个 |
最后一个 |
最大主机数 |
A |
126(2(7)-2) |
1 |
126 |
16777214 |
B |
16384 |
128.0 |
191.255 |
65534 |
C |
2097152 |
192.0.0 |
223.255.255 |
254 |
B类埴的子网划分:
子网号的比特数 |
子网掩码 |
子网数 |
主机数/子网 |
2 |
255.255.192.0 |
2 |
16382 |
3 |
255.255.224.0 |
6 |
8190 |
4 |
255.255.240.0 |
14 |
4094 |
5 |
255.255.248.0 |
30 |
2046 |
6 |
255.255.252.0 |
62 |
1022 |
7 |
255.255.254.0 |
126 |
510 |
8 |
255.255.255.0 |
254 |
254 |
9 |
255.255.255.128 |
510 |
126 |
10 |
255.255.255.192 |
1022 |
62 |
11 |
255.255.255.224 |
2046 |
30 |
12 |
255.255.255.240 |
4094 |
14 |
13 |
255.255.255.248 |
8190 |
6 |
14 |
255.255.255.252 |
16382 |
2 |
关键字:
递归:(Recrusive)
多态:
引用:
继承:
调试用例:Test
地址解析协议:ARP
逆地址解析协议:RARP(ReverseAddress Resolution Protocol)
26. 描述内存分配方式以及它们的区别?
1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
2。死锁
死锁就是两个或多个进程无止境地等候着永远不会成立的条件的一种系统状态
在两个或多个并发进程中,如果每个过程持有某中资源而又都等待着别的进程释放它或他们现在白吃的资源,否则就不能向前推进。
死锁产生原因:⒈系统资源不足⒉进程推进顺序非法
产生死锁的4个必要条件:
①互斥条件②不剥夺条件③部分分配④环路条件
解决死锁策略:
⒈采用静态分配方法来预防死锁(静态预防)
⒉采用有控分配方法来避免死锁(动态避免)
⒊当死锁发生时检测出死锁并设法修复