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; //返回环的入口地址
}