通訊錄項目整理(鏈表法)

本文介紹了我通訊錄項目各個功能的編寫過程以及大體思路。

1.頭文件以及結構體的定義

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef char Elemtype;
typedef char Status;
typedef struct Node
{
	Elemtype name[10];
	Elemtype tel[12];
	struct Node *next;
}Node,*Address_list;

2.初始化過程

    申請頭結點,使用malloc函數爲頭結點分配空間,讓頭指針指向頭結點,頭結點的指針域指向NULL。

    爲什麼要申請頭結點?

    爲了保證處理第一個節點(非頭結點)和後面節點時候設計的算法相同,實現程序的高效性。

/************初始化****************/
Status Initaddress(Address_list *aptr)
{
	Node *p=(Node *)malloc(sizeof(Node));//申請頭結點
	if(p==NULL)
		return ERROR;
	p->next=NULL;
	*aptr=p;
	return OK;
}

2.插入新節點(實現新建聯繫人功能)

  第一步:申請一個新結點用於記錄新聯繫人的信息

                   使用malloc函數,需要強制轉換。

  第二步:將這個新結點插入到鏈表的最後

                   新申請一個tmp指針指向tmp頭結點,用while語句是tmp指針後移,直到鏈表尾部,即tmp->next的值爲NULL時,進行                如下操作:

                   將tmp指向新申請的結點,新節點的指針域指向NULL。

Status Insert(Address_list aptr,Elemtype e[],Elemtype f[])
{
	Node *p=(Node *)malloc(sizeof(Node));
	if(p==NULL)
	{
		printf("堆空間已滿\n");
		return ERROR;
	}
	strcpy(p->name,e);
	strcpy(p->tel,f);
	Address_list tmp=aptr;
	while(tmp->next!=NULL)
	{	
		tmp=tmp->next;
		if(strcmp(e,tmp->name)==0)
		{
			printf("此聯繫人已存在!\n");
			return ERROR;
		}
	}
	p->next=NULL;
	tmp->next=p;
	return OK;
}

4.刪除結點(刪除聯繫人)

  第一步:找到需要刪除的結點

                 使用strcmp函數將需要刪除聯繫人姓名與鏈表結點中數據依次對比,相同則執行第二步刪除工作,不同與下一個結點對比,若是到鏈表結尾依然沒有找到,則代表該聯繫人不存在。

  第二步:刪除該結點

Status Delete(Address_list aptr,Elemtype e[],Elemtype f[])   
{
	Address_list tmp=aptr;
	
	while(1)
	{
		if(strcmp(e,tmp->next->name)==0)
			break;
		if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
		{
			printf("此聯繫人不存在!\n");
			return ERROR;
		}
		tmp=tmp->next;
	}
	Node *tmp2=tmp->next;
	strcpy(e,tmp2->name);
	strcpy(f,tmp2->tel);
	tmp->next=tmp2->next;
	free(tmp2);
	return OK;
}

5.查找聯繫人

   查找與上文刪除聯繫人的第一步相同,使用strcmp函數即可,然後將該結點信息打印,較爲簡單。

Status Find(Address_list aptr,Elemtype e[],Elemtype f[])
{
	Address_list tmp=aptr;
	while(1)
	{
		if(strcmp(e,tmp->next->name)==0)
			break;
		if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
		{
			printf("此聯繫人不存在!\n");
			return ERROR;
		}
		tmp=tmp->next;
	}
	strcpy(f,tmp->next->tel);
	return OK;
}

6.按聯繫人姓名修改號碼

    第一步:找到該結點,同上文查找

    第二步:修改信息,用strcpy函數將修改後的號碼賦值給該結點的Tel域

Status Modify(Address_list aptr,Elemtype e[],Elemtype f[])
{
	Address_list tmp=aptr;
	while(1)
	{
		if(strcmp(e,tmp->next->name)==0)
			break;
		if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
		{
			printf("此聯繫人不存在!\n");
			return ERROR;
		}
		tmp=tmp->next;
	}
	strcpy(tmp->next->tel,f);
	return OK;
}

7.打印函數

Status Printlist(Address_list aptr)
{
	Address_list tmp=aptr;
	if(NULL==tmp)
	{
		printf("此表爲空!\n");
		return ERROR;
	}
	else
	{
		while(tmp!=NULL)
		{
			printf("%-10s",tmp->name);
			printf("%s",tmp->tel);
			printf("\n");
			tmp=tmp->next;
		}
		printf("\n");
		return OK;
	}
}

8.將聯繫人按首字母排序

   第一步:申請一個指針數組用於依次指向鏈表的每一個結點

   第二步:將指針數組的內容進行排序

   第三步:打印指針數組的內容

Status Sort(Address_list aptr)
{
	int m=0;
	Address_list tmp=aptr;
	Node *a[100];
	tmp=tmp->next;
	while(tmp!=NULL)
	{
		a[m]=tmp;
		m++;
		tmp=tmp->next;
	}
	int i;
	for(i=0;i<m-1;i++)
	{
		int j;
		for(j=0;j<=m-2-i;j++)
		{
			if(strcmp(a[j]->name,a[j+1]->name)>0)
			{
				Node *tmp;
				tmp=a[j];
				a[j]=a[j+1];
				a[j+1]=tmp;
			}
		}
	}
	for(i=0;i<m;i++)
	{
		printf("%-10s",a[i]->name);
		printf("%s",a[i]->tel);
		printf("\n");
	}
	return OK;
}

9.將通訊錄的聯繫人信息保存到另一個TXT文件中

   第一步:創建新的TXT文件

   第二步:將鏈表信息逐個寫入TXT文件中,用fwrite函數

Status Fwrite(Address_list aptr)
{
	FILE *file=fopen("test5.txt","w+");
		if(NULL==file)
		{
			perror("fopen");
			return ERROR;
		}
	Address_list tmp=aptr;
	tmp=tmp->next;
	while(tmp!=NULL)
	{
		int count1=fwrite(tmp,sizeof(Node),1,file);
		if(EOF==count1)
		{
			perror("fwrite");
			fclose(file);
			return ERROR;
		}
		tmp=tmp->next;
	}
	
	return OK;
}

10.讀取TXT文件中的聯繫人信息

     第一步:打開存有聯繫人信息的TXT文件

     第二步:逐個讀取聯繫人信息,用fread函數

Status Fread(Address_list aptr)
{
	Address_list tmp=aptr;
	FILE *file=fopen("test5.txt","a+");
		if(NULL==file)
		{
			perror("fopen");
			return ERROR;
		}
	fseek(file,0,SEEK_SET);
	Node *p=(Node *)malloc(sizeof(Node));
	while(fread(p,sizeof(Node),1,file)!=0)
	{
		p->next=NULL;
		tmp->next=p;
		tmp=tmp->next;
		p=(Node *)malloc(sizeof(Node));
	}
	free(p);
	return OK;
}

11.主函數

  在主函數中引用上面寫好的各個函數,再用一個switch函數實現執行時的供能選擇。

int main()
{
	Address_list Ltop;
	Initaddress(&Ltop);
	//Insert(Ltop,"yu","13327829295");
	Fread(Ltop);
	Printlist(Ltop);
	Elemtype name[10];
	Elemtype tel[12];
	while(1)
	{
		int i;
		printf("\t\t\t1.查看通訊錄\n");
		printf("\t\t\t2.新建聯繫人\n");
		printf("\t\t\t3.刪除聯繫人\n");
		printf("\t\t\t4.查找聯繫人\n");
		printf("\t\t\t5.按聯繫人修改號碼\n");
		printf("\t\t\t6.按聯繫人姓名排序\n");
		printf("\t\t\t0.終止程序\n");
		scanf("%d",&i);
		switch(i)
		{
			case 1:
				Printlist(Ltop);
				break;
			case 2:
				do
				{
					printf("請輸入新建聯繫人的姓名\n");
					scanf("%s",name);
					printf("請輸入新建聯繫人的手機號\n");
					scanf("%s",tel);
				}
				while(!Insert(Ltop,name,tel));
				Fwrite(Ltop);
				break;
			case 3:
				do
				{
					printf("請輸入刪除聯繫人的姓名\n");
					scanf("%s",name);
				}
				while(!Delete(Ltop,name,tel));
				printf("刪除的聯繫人爲:%s 號碼爲%s\n",name,tel);
				Fwrite(Ltop);
				break;
			case 4:
				do
				{
					printf("請輸入查找聯繫人的姓名\n");
					scanf("%s",name);
				}
				while(!Find(Ltop,name,tel));
				printf("%s的號碼爲:%s\n",name,tel);
				break;
			case 5:
				do
				{
					printf("請輸入要修改號碼的聯繫人姓名\n");
					scanf("%s",name);
				}
				while(!Modify(Ltop,name,tel));
				printf("請輸入修改後的號碼:\n");
				scanf("%s",tel);
				Modify(Ltop,name,tel);
				printf("修改後%s的號碼爲:%s\n",name,tel);
				Fwrite(Ltop);
				break;
			case 6:
				Sort(Ltop);
				break;
			case 0:
				return 0;
			default:
				printf("輸入選項有誤\n");
				break;
		}
	}
	return 0;
}

通訊錄項目至此結束。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章