软件工程师面试编程常见函数实现

来源:互联网 发布:淘宝贺卡怎么写 编辑:程序博客网 时间:2024/06/11 22:33

1、引用与指针区别:引用必须初始化,不可以改变值,不可指向NULL。
2 、字符串比较,判断2个字符串是否相等:
int strcmp(char  *source, char *dest) 相等返回0,不等返回-1;{     ASSERT((source!=NULL)&&(dest!=NULL)); //判断指针是否为空,如果为空,则报错。   int i,j;     for(i=0; source[i]==dest[i]; i++)    {          if(source[i]==’/0 && dest[i]=='/0')    //如果source和dest字符串同时到了尾部,则返回0.             return 0;         else                 return -1;     }}



3 .字符串复制,遇到'/0'立即停止复制。
char *strcpy(char *strDest, const char *strSrc) //注意,按道理,source字符串应该是const,所以用const *src修饰。{   ASSERT(strDest != NULL && strSrc != NULL);   char *addr = strDest; //创建一个指针,指向strDest的存储区域   while(*strDest++=*strSrc++)         NULL; //NULL可以省略,但更有利于编译器发现错误   return addr;}


4、子串查找,返回子字符串所在位置
int strindex(char *str,char *substr)  //在str中,查找substr,返回索引位置。{      int end,i,j;   end = strlen(str) - strlen(substr);  /*计算结束位置*/   if ( end > 0 )                       /*子串长度必须小于str字符串*/   {         for ( i = 0; i <= end; i++ )         for ( j = i; str[j] == substr[j-i]; j++ ) /* 用循环比较 */            if ( substr[j-i+1] == '/0' )           /* 子串查找结束*/               return i + 1;                       /* 找到了子串*/      } //if  return -1; //子串长度大于要str}


4 、memcpy() 用来拷贝src前n个字节到dest所指的地址上。

       与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'/0'而结束。函数返回指向dest的指针。

void *memcpy(void* dest,const void* src, int size){void* pDest = (char*)dest; // memcpy函数原型里面的参数是void*,这里用(char*)做强制类型转换。void* pSrc = (char*)src;ASSERT(dest != NULL && src != NULL);/*下面ASSERT,用来判断memcpy会不会有重叠。如果重叠,就不要使用memcpy()而使用memmove()函数。 */ASSERT(pDest>=pSrc+size || pSrc>=pDest+size);while(size-->0)            *pDest++ == *pSrc++;return dest;}
 
5、memmove(),对比memcpy()。
void *Memmove(void *Dest, const void*Src,int count){ASSERT(Dest!=NULL && Src!=NULL);void* pDest = Dest;if (Dest<Src && (char*)Dest > (char*)Src + count) //判断内存移动时,确定没有地址重叠   {             while(count--)                  *(char*)Dest++ = *(char*)Src++;     }else // 有地址重叠,从src的串尾开始复制   {           Dest = (char*)Dest + count - 1;          Src = (char*)Src + count - 1;//指向串尾,从尾部开始复制        while(count--)                 *(char*)Dest- - = *(char*)Src- -;    }return Dest;} 
 
6、单链表插入删除节点
首先,定义一个单链表结构体,包含数据和指针(指向下一个数据)
struct linklist      {int data;      struct linklist*next;      }; 
 
【6.1】单链表插入节点
     在单链表节点p后面插入s节点:只需这2步关键步骤
    (1)s=(Linklist*)malloc(sizeof(Linklist); 
    (2)s->next=p->next ;   p->next=s;
      完整程序如下:
/***************单链表插入节点********************/int listinsert(linklist *head,int i , int data){       linklist *p,*s;int j=0;       p=head;while(p && j++<i) { p=p-next;} //查找插入第i-1个位置if(p==NULL ||  j>i) {   cout<<"Positon Error";    return 0;}s=(linklist*)malloc(sizeof(linklist));assert(s!=NULL);s->data=data; s->next=p->next; p->next=s;//在第i-1个位置后面,即指针p后面插入datareturn 1;}
 
【6.2】单链表删除节点
/***************单链表删除节点********************/int listdelete(linklist *head,int i){       linklist *p,*q;int j=0;       p=head;while(p->next && j++<i) { p=p-next;} //查找第i-1个位置,待删除节点的前一个节点if(p->next==NULL ||  j>i) {   cout<<"Positon Error";    return 0;}q=p->next; p->next=q->next;//删除节点ireturn 1;}
 
7、 翻转链表(链表逆序),常见面试题。
void reverselinklist(linklist *head){    linklist *pre,*curr;//设置两个指针    pre=head;    curr=head->next;    head->next=NULL;    while(curr!=NULL)             {               pre=curr;              curr=curr->next;              pre->next=head->next;              head->next=pre; //在head后面依次插入各个pre            }} 
 
8、实现有序链表上的插入
void linklist(linklist head ,elemtype x){   linklist pre,curr, q;    pre=head;    curr=head->next;   while( curr!=NULL  &&  curr->data<=x )  //x为要插入的数据           {                pre=curr;                 curr=curr->next; //循环向后移动这2个指针,直至找到插入位置           }    q =(linklist *)malloc(sizeof(linklist));   assert(q!=NULL);//判断是否成功分配内存   q->data=x ;     //申请节点,插入数据x   q->next=pre->next ;    pre-next=q;  }
 
9、折半查找干啥用?( 用于对递增顺序表的查找)
int zheban(int *t){    low=0;    high=length-1;    while(low<=high)          {              mid=(low+high)/2;               if (table[mid].data=x)                        return mid;              else                    {                          if(x<t[mid].data)                                    high=mid-1;                         else                                    low=mid+1;                }           } //while    return -1;}
 
10、双向链表删除节点P,P后插入节点;
 
首先,定义一个双向链表的结构体元素。 
struct link{  struct link *prior; //前驱   int data;   struct link *next; //后继};
  
/********************双向链表删除操作***************************/int ListDelete_DuL(struct link *head, int num){   struct link *p;     p=head->next;   while(p&&p->data!=num)          p=p->next;//查找要删除的结点   if(p!=NULL)   {       p->pre->next=p->next;       p->next->pre=p->pre;       p->pre=NULL;         p->next=NULL;       free(p);           return 1;// 比如要查找某元素,找到就返回1,没找到返回0。用来判断结果的   }  else      {           return 0;   }}/********************双向链表插入操作*****************************/int ListInsert_DuL(DuLinkList *head,int num){   struct link *p,*q;   p=head->next;   while(p&&p->data!=num)  p=p->next; // 查找插入位置   if(p!=NULL)   {         q=(struct link *)malloc(sizeof(struct link));        ASSERT(q!=NULL);        q->data=num;      q->pre=p;//插入节点      q->next=p->next;      p->next->pre=q;      p->next=q;           return 1;  }    else        {         return 0;      }}