面试WH mystcpy mystrnpy 链表

strcpy

strncpy


#include <stdio.h>
#include <assert.h>

char *mystrcpy(char *dest, const char *src)
{
	int i = 0;
	for(i = 0; (dest[i] = src[i]); i++)
	{
		;
	}
	return dest;
}

char *mystrcpy1(char *dest, const char *src)
{
	assert( (dest != NULL)&&(src != NULL) );

	char *address = dest;
	while( (*dest++ = *src++) != '\0' )
	{
		;
	}
	return address;
}

char *mystrncpy(char *dest, const char *src, int n)
{
	assert( (dest != NULL)&&(src != NULL) );

	int i = 0;
	for(i = 0; (dest[i] = src[i])&&( n > 0 ) ; i++, n--)
	{
		;
	}
//hello   3
//n = 3       i=0 d[0]=h i=1 n=2, i=1 d[1]=e i=2 n=1, i=2 d[2]=l i=3 n=0 
//hel i=3 n=0
	while(n >= 0)
	{
		dest[i++] = '\0';
		n--;
	}

	return dest;

}



int main(int argc, char *argv[])
{
	char *str1 = "helloworld";
	char str2[1024];
	char str3[1024];
	char str4[1024];
	printf("mystrcpy\nbefore:%s  after:%s\n", argv[1], mystrcpy(str2, argv[1]));
	printf("mystrcpy1\nbefore:%s  after:%s\n", str1, mystrcpy1(str3, str1));
	printf("mystrncpy\nbefore:%s  after:%s\n", str1, mystrncpy(str4, str1,5));
}


/*
lin@a46cb:~/wh$ ls
mystrcpy  mystrcpy.c
lin@a46cb:~/wh$ gcc mystrcpy.c -o mystrcpy
lin@a46cb:~/wh$ ./mystrcpy GG
mystrcpy
before:GG  after:GG
mystrcpy1
before:helloworld  after:helloworld
mystrncpy
before:helloworld  after:hello
lin@a46cb:~/wh$ 
*/


链表的基础操作

/*
 链表的操作
 */

#include <stdio.h>
#include <stdlib.h>


typedef struct node{
	char sex;
	int age;
	struct node *next;
}node_t;

typedef struct node * list_node;

list_node mk_node(char s, int a) //创建链表节点
{
	list_node p = malloc(sizeof(node_t));

	if(p != NULL) //malloc 链表创建ok 
	{
		p->sex = s;
		p->age = a;
		p->next = NULL;
	}
	return p;
}


//从头插入
list_node insert_head(list_node head, char s, int a)
{
	list_node newp = mk_node(s, a);

	if( (head == NULL) || (newp == NULL))
	{
		if(head == NULL)
		{
			head = newp;
		}
		return head;
	}

	newp->next = head;
	head = newp;
	return head;
}

//从尾插入
list_node insert_tail(list_node head, char s, int a)
{

	list_node newp = mk_node(s, a);
	list_node tail;

	if( (head == NULL) || (newp == NULL) )
	{
		if(head == NULL)
		{
			head = newp;
		}
		
		return head;
	}

	//这时 tail为head,若tail->next为NULL,跳出循环,否则tail向后移一节点
	//直到找到链表的最后一个节点
	for(tail = head; tail->next; tail = tail->next) 
	{
		;
	}

	tail->next = newp;//把新节点链接到尾节点上
	return head;
}

//删除结点
list_node del_node(list_node headp, int key)
{
	list_node del, pre, cur;//pre 前缀 current 当前

	//若头结点为NULL
	if(headp == NULL)
		return NULL;

	//若头结点为删除的结点
	if(headp->age == key)
	{
		del = headp;
		headp = headp->next;
		del->next = NULL;
		return del;
	}

	for(pre = headp, cur = headp->next; cur;
					pre = pre->next, cur = cur->next)
	{
		// (pre) - (cur) - (cur->next) 
		//删除cur结点 
		//1.先把cur 赋值给del 
		//2. cur->next(第三个结点)给cur. cur=cur->next cur现在为第三个节点
		//3.把del的节点的next置NULL. del->next = NULL
		//4.将第一个节点pre,链接到第三个,第二个已被删除  pre->next = cur;

		if(cur->age == key) 
		{
			del = cur;
			cur = cur->next;
			del->next = NULL;
			pre->next = cur;
			return del;
		}
	
	}

	return NULL;


}





//销毁链表
void destroy_list(list_node head)
{
	list_node cur, next;

	//1 cur = head, 2 cur 判断条件 3,执行{}条件 4,cur = next
	for(cur = head; cur; cur = next)
	{
		next = cur->next;
		free(cur);
	}
}


//打印节点
void display_link_list(list_node head)
{
	list_node cur; //当前节点

	for(cur = head; cur; cur = cur->next ) 
	{
		printf("sex:%c age:%d\n", cur->sex, cur->age);
	}

}


int main(int argc, char *argv[])
{

	list_node head = NULL, del;


	char ch_sex;
	int n_age;
	
	while(1)
	{
		scanf("%c %d", &ch_sex, &n_age);
		getchar();//吃掉回车

		if(n_age == 0)
			break;

		head = insert_head(head, ch_sex, n_age);
	
	}

	printf("-------------------\n");
	display_link_list(head);


	printf("-------------------\n");
	while( (del = del_node(head, 9)) )
	{
		printf("del node:%c %d\n", del->sex, del->age);
		free(del);
	}
	printf("-------------------\n");


	display_link_list(head);


	return 0;
	
}


/*
lin@a46cb:~/wh$ ./linklist 
w 2
e 4
q 1
y 6
x 8
z 9
n 5
n 0
-------------------
sex:n age:5
sex:z age:9
sex:x age:8
sex:y age:6
sex:q age:1
sex:e age:4
sex:w age:2
del node:z 9
sex:n age:5
sex:x age:8
sex:y age:6
sex:q age:1
sex:e age:4
sex:w age:2
lin@a46cb:~/wh$ 
*/



链表常见面试题


/* 链表常见面试题*/

#include <stdio.h>

struct node
{
	int data;
	struct node * next;
};

//两链表是否相交.相交为1,不相交返回0
int link_is_cross(node *head1, node *head2)
{
	node *p1, *p2;

	for(p1 = head1; p1; p1 = p1->next )
	{
		;
	}
//	for(p1 = head1; p1->next != NULL; p1++ )
	for(p2 = head2; p2; p2 = p2->next)
	{
		;
	}

	return p2 == p1 ? 1 : 0;
}


//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------

//判断链表是否有环

bool linklist_is_loop(LinkList *head)
{
	LinkList *pfast = head;
	LinkList *pslow = head;

	//如果无环,则fast先走到终点
	//当链表长度为奇数时,fast->next 为空
	//当链表长度为偶数时,fast 为空
	while( (pfast != NULL) && (pfast->next !== NULL))
	{
		pslow = pslow->next;
		pfast = pfast->next->next;

		if(pfast == pslow) //指针相遇,有环
			return true; 
	}

	return false; //没有环

}

/*---------------------------------------
给出两个单向链表的头指针pHead1和pHead2,判断这两个链表是否相交,
若相交返回第一个相交的节点。假设两个链表均不带环。

方法:
对第一个链表遍历,计算长度len1,同时保存最后一个节点的地址。
对第二个链表遍历,计算长度len2,同时检查最后一个节点是否和第一个链表的最后一个节点相同,若不相同,则不相交,程序结束。
若相交,两个链表均从头节点开始,假设len1大于len2,那么将第一个链表先遍历len1-len2个节点,此时两个链表当前节点到第一个相交节点的距离就相等了,
比较下一个节点是不是相同,如果相同就返回该节点(即相交节点),若不相同,两个链表都同步向后走一步,继续比较。

方法:
由于两个链表都没有环,我们可以把第二个链表接在第一个链表的后面,如果得到的链表有环,则说明这两个链表相交。否则,这两个链表不相交。
这样我们就把问题转化为判断一个链表是否有环了。最后,当然可别忘记恢复原来的状态,去掉从第一个链表到第二个链表表头的指向。

---------------------------------------*/



/*****************************************************/
/*
给出一个单向链表的头指针pHead,判断链表中是否有环,若存在,则求出进入环中的第一个节点*/
/*
首先使用快、慢指针来判断链表是否存在环,若不存在结束。
若链表中存在环,我们
从链表头、与两个指针的相遇点
分别设一个指针.
然后每次各走一步,两个指针必定相遇,且相遇的第一个点为环的入口点。
*/

//找到环的第一个入口
LinkList * find_loop_node(LinkList *head)
{
	LinkList * pslow = head;
	LinkList * pfast = head;

	while( (pfast->next != NULL) && (pfast != NULL) )
	{
		pfast = pfast->next->next;
		pslow = pslow->next;

		if(pslow == pfast)
			break; //说明有环
	}

	if( pfast == NULL || pfast->next == NULL )
		return NULL;

//从链表头、与两个指针的相遇点
//分别设一个指针.
//然后每次各走一步,两个指针必定相遇,且相遇的第一个点为环的入口点。

	pslow = head; //pslow为链表头,pfast现在为两指针的相遇点
	while(pslow != pfast)
	{
		pslow = pslow->next;
		pfast = pfast->next;
	}

	return pslow; //返回环的入口地址

}












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值