面试准备—数据结构

来源:互联网 发布:程小青 知乎 编辑:程序博客网 时间:2024/05/18 01:46

记录一下经典的算法

1、合并两个链表

LA、LB中的数据元素按值非递减有序排列,现要求将LA、LB归并为一个新的线性表LC,且LC中的数据元素仍按值非递减有序排列。

方法:

先设LC为空表,然后将LA、LB中的元素逐个插入到LC中,可设两个指针i、j分别指向LA、LB中的某个元素,若设i当前所指的元素为a,j当前所指的元素为b,则当前应插入到LC中的元素c为

指针i和j的初值均为1,在所指元素插入LC之后,在LA或LB中顺序后移。

算法:

void MergeList(List La,List Lb,List &Lc)

{

InitList(Lc);

int i=j=1;

int k=0;

int La_len = ListLength(La);

int Lb_len = ListLength(Lb);

while( (i<=La_len) && (j<=Lb_len) )

{

GetElem( La,i,ai );

GetElem( Lb,j.bj );

if( ai<=bj )

{

ListInsert( Lc,++k,ai );

++i;

        }

else

{

ListInsert( Lc,++k,bj );

++j;

}

while( i<=La_len )

{

//Lb链表插入完毕,然后插入剩余的La

GetElem( La,i++,ai );

ListInsert( Lc,++k,ai );

}

while( j<=Lb_len)

{

//La链表插入完毕,然后插入剩余的Lb

GetElem( Lb,j++,bj );

ListInsert( Lc,++k,bj );

}

}

}

2、编写一个高效率的函数找出字符串中第一个无重复的字符。

char GetFirstNonRepeat( char* str)

{

char * pStr = str;

int nNum[256];

for( int i =0; i<256; i++)

{

nNum[i] = 0;

}

while(  *pStr != '\0' )

{

nNum[*pStr]++;

pStr++;

}

pStr = str;

while( *pStr != '\0' )

{

if( nNum[*pStr] ==1)

{

return *pstr;

}

pStr++;

}

    return -1;

}

3、编写strlen实现函数,要求不能使用任何变量

int strlen( char * str )

{

return *str?1+strlen( str +1):0;

}

4、将链表转置

List * Reverse( List* L )

{

if( !L || !L->next )

return L;

List* n = Reverse( L->next );

L->next->next = L;

L->next = NULL;

return n;

}

5、计算二叉树的高度

int TreeHeight( btree * t)

{

if( t == NULL)

return 0;

else

{

h1 = TreeHeight( t->left );

h2 = TreeHeight( t->right );

if( h1>=h2 )

{

h = h1+1 ;

}

else

{

h = h2+1;

}

return h;  

}

}

6、复制二叉树

btree* copy( btree* t )

{

if( t!= NULL)

{

btree *p = (btree*)malloc( sizeof(btree) );

if( p != NULL )

{

p->data = t->data;

p->left = copy( t->left );

p->right = copy( t->right );

return p;

}

}

else

{

return  NULL;

}

}

7、交换链式存储的二叉树的左右子树

btree* swap( btree* t )

{

if( t!= NULL)

{

b = ( btree* ) malloc ( sizeof(btree) );

b->data = t->data;

b->right = swap( t->left );

b->left = swap( t->right );

return b;

}

else return NULL;

}

8、统计所有叶子结点数

int GetLeafNum( btree* b )

{

if( b == NULL)

return 0;

else if( b->left == NULL && b->right == NULL)

return 1;

else

{

num1 = GetLeafNum( b->left );

num2 = GetLeafNum( b->right );

return num1+num2;

}

}


****初始化一个线性表*****

typedef struct

{

ElemType *elem;//存储空间基址

int length;//当前数组长度

int listsize;//当前分配的存储空间(以sizeof(ElemType)为单位)

}Sqlist;

void InitList_Sq( SqList &List)

{

List.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));

if( !List.elem )

exit( OVERFLOW );

List.length = 0;

List.listsize = LIST_INIT_SIZE;

}

****在线性表中第i个位置之前插入新的元素****

void ListInsert_Sq( SqList &L, int i, ElemType e )

{

if( i<1 || i>L.length+1 ) return ERROR;

if( L.length >= L.listsize )

{

//当前存储空间已满,需增加分配空间

newbase = ( ElemType* )realloc( L.elem, (L.listsize + LISTINCREMENT )*sizeof(ElemType) );

if( !newbase ) exit( OVERFLOW );

//分配成功

L.elem = newbase;

L.listsize += LISTINCREMENT;

}

q = &( L.elem[i-1] );

for( p = &( L.elem[L.length -1]); p>=q; --p)

*(p+1) = *p;

*q = e;

L.length ++;

}

****删除元素****

void ListDelete_Sq( SqList &L, int i ,ElemType &e)//删除第i个元素,并用e返回元素值

{

if( i<1|| i>L.length ) return;

p = &(L.elem[ i -1 ]);

e = *p;

q = L.elem+L.length -1;

for( ;p<p ; ++p)

{

*p = *(p+1);

}

L.length--;

}


-----------------------------树和二叉树---------------------------------------------

定义:

结点的度: 结点拥有的子树数;

树的度:树内各结点的度的最大值;

结点的层次:根为第一层;

树中结点的最大层次称为树的深度;

-------------------二叉树-----------------------------------

二叉树性质:

1、在二叉树的第i层上至多有个结点;

2、深度为k的二叉树至多有个结点;

3、对于任何一棵二叉树T,如果其终端节点数为n0,度为2的结点数为n2,则n0=n2+1;

完全二叉树性质:

1、具有n个结点的完全二叉树的深度为

2、对于一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1<=i<=n),有

2.1 如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点

2.2 如果2i>n,则结点i无左孩子;否则其左孩子是结点2i;

2.3 如果2i+1>n,则结点i无右孩子,否则其右孩子是结点2i+1;


遍历二叉树

1、先序遍历:先访问根节点,先序遍历左子树,先序遍历右子树

2、中序遍历:中序遍历左子树,访问根结点,中序遍历右子树

3、后序遍历:后序遍历左子树,后序遍历右子树,访问根结点

时间复杂度为O(n)


最优二叉树(赫夫曼树)

是一类带全路径长度最短的树

路径长度:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上的分支数目称作路径长度

树的路径长度:从树根到每一个结点的路径长度之和。


查找

折半查找:先确定待查记录所在的范围,然后逐步缩小范围直到找或找不到该记录位置。

算法

int Search_Bin(SSTable ST,KeyType key)

{

low = 1;

high = ST.length;

while( low<=high)

{

mid = (low+high)/2;

if( EQ(ST.elem[mid].key,key) ) return mid;

else if( LT(key,ST.elem[mid].key) ) high = mid-1;

else low = mid+1;

}

return 0;

}

折半查找法在查找成功时和给定值进行比较的关键字个数至多为

二叉排序树

性质:

或者是一棵空树,或者具有下列性质的二叉树:

1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

3)它的左右子树也分别为二叉排序树。

算法

BiTree SearchBST(BiTree T,KeyType key)

{

if( (!T) || EQ( key,T->data.key) ) return T;

else if( LT( key, T->data.key)) return SearchBST( T->lchild,key);

else return SearchBST( T->rchild,key);

}

顺序查找的平均查找长度为3/4(n+1)

折半查找的平均查找长度为

二叉排序树的时间复杂度为O(logn)

平衡二叉树查找的时间复杂度为O(logn)

































































































































































原创粉丝点击