4-6 带头结点的链式表操作集
code:
List MakeEmpty()
{
List L;
L = (List)malloc(sizeof(struct LNode));
L->Data = NULL;
L->Next = NULL;
return L;
}
Position Find( List L, ElementType X )
{
List p = L;
while(p && p->Data!=X) {
p = p->Next;
}
if(p && X==p->Data) {
return p;
} else {
return ERROR;
}
}
bool Insert( List L, ElementType X, Position P )
{
List r = L;
List pre = L;
while(r && P!=r) {
pre = r;
r = r->Next;
}
if(r==P) {
List p = (List)malloc(sizeof(struct LNode));
p->Data = X;
p->Next = r;
pre->Next = p;
return true;
}
printf("Wrong Position for Insertion\n");
return false;
}
bool Delete( List L, Position P )
{
List r = L;
List pre = L;
while(r && r!=P)
{
pre = r;
r = r->Next;
}
if(r==P) {
pre->Next = P->Next;
free(P);
List k = pre->Next;
return true;
}
printf("Wrong Position for Deletion\n");
return false;
}
P.S:这道题需要写四个函数,分别是链表的置空,查询某个元素,还有元素的插入和删除,都是一些链表的基本操作,题中的链表是有头节点的,而开始的题中的链表是没有使用头节点的,这个与前面的有一些区别,其实拥有头节点的链表更容易操作,在插入时不用考虑是否是第一个结点了,更加好写些,同样要注意Find函数,它需要返回的是这个元素的Position,而它是一个指针变量,而不是代表其位置的整型变量。
4-7 在一个数组中实现两个堆栈
P.S:很头疼,这一题没有通过,报的错误也是十分无奈,超时,所以也不知道怎样去解决这个问题,如何去优化代码,这道题其实是一个数组嘛,两个栈的栈底在两头,设计应该就是这样,但是给我报超时错误,暂时先放下吧,以后通过再补上来。
更新:补上成功的code,今天突然再次提交,居然就通过了,看来我的想法是没有问题的^_^
code:
Stack CreateStack( int MaxSize )
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->MaxSize = MaxSize;
S->Data = (ElementType *)malloc(sizeof(ElementType)*MaxSize);
S->Top2 = MaxSize;
S->Top1 = -1;
return S;
}
bool Push(Stack S, ElementType X, int Tag){
if(S->Top1+1 == S->Top2){
printf("Stack Full\n");
return false;
}else{
if(Tag == 1){
S->Top1++;
S->Data[S->Top1] = X;
}else{
S->Top2--;
S->Data[S->Top2] = X;
}
}
return true;
}
ElementType Pop(Stack S, int Tag){
int X;
if(Tag == 1){
if(S->Top1 == -1){
printf("Stack 1 Empty\n");
return ERROR;
}else{
X = S->Data[S->Top1];
S->Top1--;
return X;
}
}else if(Tag == 2){
if(S->Top2 == S->MaxSize){
printf("Stack 2 Empty\n");
return ERROR;
}else{
X = S->Data[S->Top2];
S->Top2++;
return X;
}
}
}
4-8 求二叉树高度
code:
int GetHeight( BinTree BT )
{
if (BT == NULL)
return 0;
else {
int left = GetHeight(BT->Left);
int right = GetHeight(BT->Right);
if(left>=right)
return 1 + left;
else
return 1 + right;
}
}
P.S:求一颗二叉树的高度,我直接使用了递归实现,所以也十分的清晰易懂。
4-9 二叉树遍历
这道题吧,也木有通过,其实是不愿写吧,前序,中序,后续遍历都很简单,但是层序便利时,我们知道需要借助队列来实现,而在函数题中又不能用那种头文件,因此我想了想,但后来脑子就不舒服,先放下,后面补上。
更新:今天想了想,其实没有必要用队列的,可以简单点嘛,开始怎么就那么蠢呢,队列也是由数组或链表构成的,而这道题又不需要考虑队列满或者空的情况,自己用一个数组代替不就是了,其实很简单的啦,我才用了一个容量为100的数组来模拟队列,最后就这样成功啦,前中后三种遍历就没有什么好说的咯,递归,简单易懂,用栈的话也不难,但是能简单就简单嘛
code:
void InorderTraversal( BinTree BT ){
if(BT){
InorderTraversal(BT->Left);
printf(" %c", BT->Data);
InorderTraversal(BT->Right);
}
}
void PreorderTraversal( BinTree BT ){
if(BT){
printf(" %c",BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
}
void PostorderTraversal( BinTree BT )
{
if(BT != NULL){
PostorderTraversal(BT->Left);
PostorderTraversal(BT->Right);
printf(" %c", BT->Data);
}
}
void LevelorderTraversal( BinTree BT ) {
BinTree str[100];
int rear = -1, front = -1;
BinTree T;
if(!BT)
return;
rear = rear+1;
str[rear] = BT;
while(rear != front){
front = front+1;
T = str[front];
printf(" %c", T->Data);
if(T->Left) {
rear = rear+1;
str[rear] = T->Left;
}
if(T->Right){
rear++ ;
str[rear] = T->Right;
}
}
}
4-10 二分查找
code:
Position BinarySearch( List Tbl, ElementType K )
{
int left, right, middle;
left = 1, right = Tbl->Last;
while (left <= right)
{
middle = (left + right) / 2;
if (Tbl->Data[middle] > K)
{
right = middle - 1;
}
else if (Tbl->Data[middle] < K)
{
left = middle + 1;
}
else if(Tbl->Data[middle] == K)
{
return middle;
}
}
return NotFound;
}
P.S:二分查找算法,也叫折半查找,也就是将数组每次只查找一半,因此可以省去很多的比较次数,也就提高了效率,减少了查找时间,是一个很好,很基础的算法
*
4-11 先序输出叶结点
code:
void PreorderPrintLeaves( BinTree BT ){
if(BT != NULL){
PreorderPrintLeaves(BT->Left);
if(BT->Data >='A' && BT->Data <='z' && BT->Left == NULL && BT->Right == NULL){
printf(" %c",BT->Data);
}
PreorderPrintLeaves(BT->Right);
}
}
P.S:先序输出叶子结点,说白了就是先序遍历呗,不过在先序遍历的基础上进行一下判断,当左右子节点都为空时才输出来。
4-12 二叉搜索树的操作集
P.S:这道题部分正确,可能是没有考虑全面,前三个测试点不能通过,后两个可以,所以等通过之后再放上代码。
更新:调了很多次,这道虽然是教材上的,但是删除操作是真的很复杂,需要很细心头脑很清晰的去写,下面的是code,参考了教材上的源码,最后居然让我发现了一个小错误,教材上查找最大最小元素函数的判断语句中多了个“!”,很容易就发现啦,但是不一定会注意到,慢慢写啦!!
code:
BinTree Insert( BinTree BST, ElementType X )
{
if(!BST) { /* 若原树为空,生成并返回一个结点的二叉搜索树 */
BST = (BinTree)malloc(sizeof(struct TNode));
BST ->Data = X;
BST ->Left = BST ->Right = NULL;
}else { /* 开始寻找要插入元素的位置 */
if(X < BST ->Data ) {
BST ->Left = Insert(BST ->Left, X);
}else if(X > BST ->Data ) {
BST ->Right = Insert(BST ->Right, X);
}
/* X已经存在,不用操作 */
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X )
{
Position Tmp;
if(!BST) {
printf("Not Found\n");
}else {
if( X < BST->Data) {
BST ->Left = Delete(BST->Left, X); /* 左子树递归删除 */
}else if(X > BST->Data ) {
BST ->Right = Delete(BST->Right , X); /* 右子树递归删除*/
}else { /* 找到需要删除的结点 */
if(BST->Left && BST->Right) {
/* 被删除的结点有左右子结点 */
Tmp = FindMin( BST ->Right); /* 在右子树中找到最小结点填充删除结点 */
BST ->Data = Tmp ->Data;
BST ->Right = Delete(BST ->Right, BST ->Data); /* 在删除结点的右结点中删除最小元素 */
}else { /* 被删除结点有一个或没有子结点*/
Tmp = BST;
if(!BST ->Left) { /*有右孩子或无子结点*/
BST = BST->Right;
}else if(!BST->Right) { /* 有左孩子或无子节点*/
BST = BST->Left;
}
free(Tmp);
}
}
}
return BST;
}
Position Find( BinTree BST, ElementType X )
{
if(!BST) {
return NULL; // 查找失败
}
if(X > BST->Data) {
return Find(BST->Right, X); //在右子树中继续查找
}else if(X < BST->Data) {
return Find(BST->Left, X); //在左子树中继续查找
}else {
return BST; //查找成功
}
}
Position FindMin( BinTree BST )
{
if(BST) {
while(BST->Left) {
BST = BST->Left; //沿着左分支一直查找,直到叶子结点
}
}
return BST;
}
Position FindMax( BinTree BST )
{
if(BST) {
while(BST->Right) {
BST = BST->Right; //沿着右分支一直查找,直到叶子结点
}
}
return BST;
}
函数题就这12道,其中已经完全通过了9道,还有3道暂时没有通过,要不超时,要不部分正确,暂时想也想不出来,想的也比较难过,所以等什么时候有空无聊时再想想,然后通过了再补上吧,如果能给予想法的话请联系我呀,一起交流,一起分享,一起进步^_^
今天将原先没放上的都解决啦,12道函数题完成,虽然都是很基础的数据结构,但是真要全部靠自己写出来很困难困难,多多练习咯,后面就慢慢刷编程题咯,刷题的快感~~~