/* 知识点总结:
指针部分:
1、定义使用一个指针:
①声明 char * p;
②申请内存 p = (char *)malloc(sizeof(char)*n);malloc申请下来的内存空间用来存放*p的值;
③给指针p赋值 p = NULL;
④free(p)
2、无法把指针变量本身传递给一个函数。解决方法:①用return②用二级指针
链表部分:
1、生成
LinkList L;
L = (LinkList)malloc(sizeof(Node));
L->next = NULL;
注意:这里的参数是&L而非L。这样传递过去的是L的地址,在函数内部,用钥匙(“*”)来开锁:*(&L),其值就是L,
所以malloc分配的内存地址是真正的赋值给了L本身
2、插入
①头插
p = (LinkList)malloc(sizeof(Node)); //生成新节点
p->next = (*L)->next;
(*L)->next = p; //插入到表头
②尾插
r = *L;
p = (LinkList)malloc(sizeof(Node));
r->next = p;
r = p;
r->next = NULL;
注意:L与r的关系,L是指整个单链表,而r是指向尾结点的指针变量,r会随着循环不断地变化节点,而L则是随着循环增长为多一个节点的链表
3、删除
q = p->next;
p->next = q->next;
free(q);
4、遍历
while(p && (strcmp(name_t,p->data.name) != 0)) //遍历链表来寻找name_t
{
p = p->next;
}
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define OK 1
#define ERROR 0
struct PersonInfo
{
char name[20];
char phone[12];
};
typedef struct PersonInfo ElemType;
struct Node
{
ElemType data;
struct Node * next;
};
typedef struct Node * LinkList;
int GetElem(LinkList L,char name_t[]);
int ListInsert(LinkList * L,char * name_t,char * phone_t);
int ListDelete(LinkList * L,char * name_t);
void ShowList(LinkList L);
int ClearList(LinkList * L);
int main()
{
int n;
bool bHomeFlag = false;
char *name_t = NULL;
name_t = (char *)malloc(sizeof(char)*20);
char *phone_t = NULL;
phone_t = (char *)malloc(sizeof(char)*12);
LinkList L;
L = (LinkList)malloc(sizeof(Node));
L->next = NULL;
/*注意:这里的参数是&L而非L。这样传递过去的是L的地址,在函数内部,用钥匙(“*”)来开锁:*(&L),其值就是L,
所以malloc分配的内存地址是真正的赋值给了L本身*/
while(1)
{
printf("\n***************************************\n\
***1***: 寻找联系人\n\
***2***: 添加联系人\n\
***3***: 删除联系人\n\
***4***:显示所有联系人\n\
***5***: 格式化联系人\n\
***6***: 退出\n\
请输入您要进行的操作序号:\
\n***************************************\n");
scanf("%d",&n);
switch(n)
{
case 1:
{
printf("请输入您要查找的联系人姓名:");
scanf("%s",name_t);
GetElem(L,name_t);
break;
}
case 2:
{
printf("请输入您要添加的联系人姓名:");
scanf("%s",name_t);
getchar();
printf("请输入您要添加的联系人电话:");
scanf("%s",phone_t);
ListInsert(&L,name_t,phone_t);
break;
}
case 3:
{
printf("请输入您要删除的联系人姓名:");
scanf("%s",name_t);
ListDelete(&L,name_t);
break;
}
case 4:
{
ShowList(L);
break;
}
case 5:
{
ClearList(&L);
break;
}
case 6:
{
bHomeFlag = 1;
break;
}
default:
break;
}
if(bHomeFlag)
break;
}
free(name_t);
free(phone_t);
free(L);
return 0;
}
/* 遍历查找name_t联系人的信息并输出*/
int GetElem(LinkList L,char * name_t)
{
LinkList p;
p = L->next;
while(p && (strcmp(name_t,p->data.name) != 0)) //遍历链表来寻找name_t
{
p = p->next;
}
if(!p)
{
printf("通讯录中查无此人\n");
return ERROR;
}
printf("姓名:%s 手机号:%s\n",p->data.name,p->data.phone);
return OK;
}
/*单个元素的插入,在L中第i个位置之前插入新的数据元素e*/
int ListInsert(LinkList * L,char * name_t,char * phone_t)
{
LinkList p,s;
p = * L;
while((p->next) && (strcmp(name_t,p->next->data.name) != 1)) //遍历链表来寻找name_t应该插入的位置,按姓名字母顺序排列
{
p = p->next;
}
s = (LinkList)malloc(sizeof(Node));
strcpy(s->data.name,name_t);
strcpy(s->data.phone,phone_t);
/*插入核心代码*/
/*尾插法*/
s->next = p->next;
p->next = s;
return OK;
}
/*删除单个元素:删除L中姓名为name_t数据元素,并输出name_t的信息已删除*/
int ListDelete(LinkList * L,char * name_t)
{
char flag;
LinkList p,q;
p = *L;
while(p->next && (strcmp(name_t,p->next->data.name) != 0))
{
p = p->next;
}
if(!(p->next))
{
printf("通讯录中查无此人!\n");
return ERROR;
}
printf("是否确认删除%s?y/n\n",name_t);
getchar();
scanf("%c",&flag);
if('y' == flag)
{
/*delete 的核心代码*/
q = p->next;
p->next = q->next;
free(q);
printf("%s已经被删除\n",name_t);
}
return OK;
}
/*显示所有联系人:遍历链表,然后输出每个节点的data*/
void ShowList(LinkList L)
{
LinkList p;
p = L;
if(NULL == p->next)
{
printf("联系人为空!\n");
}
else
{
while(p->next)
{
p = p->next;
printf("姓名:%s 手机号:%s\n",p->data.name,p->data.phone);
}
}
}
/*格式化:链表的整表删除*/
int ClearList(LinkList * L)
{
LinkList p,q;
p = (*L)->next;
while(p)
{
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL;
return OK;
}
/*头插法创建链表*/
/*
void CreateLinkHead(LinkList * L,int n)
{
LinkList p; //建立一个节点用于存储要往链表里插入的中间者
int i;
srand(time(0)); //初始化随机数种子
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL; //先建立一个带头节点的单链表
for(i=0; i<n; i++)
{
p = (LinkList)malloc(sizeof(Node)); //生成新节点
p->data = rand()%100+1;
p->next = (*L)->next;
(*L)->next = p; //插入到表头
}
}
*/
/*尾插法创建链表*/
/*
void CreateLinkTail(LinkList * L,int n)
{
LinkList p,r;
int i;
srand(time(0));
*L = (LinkList)malloc(sizeof(Node));
r = *L;
for(i=0; i<n; i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100 + 1;
r->next = p;
r = p;
}
r->next = NULL;
}
*/
/*注意:L与r的关系,L是指整个单链表,而r是指向尾结点的指针变量,r会随着循环不断地变化节点,而L则是随着循环增长为多一个节点的链表*/