作业09: 简单的链表运用问题。

作业09: 简单的链表运用问题。

1.      定义一个结构体变量(包括年,月,日)编写程序,要求输入年,月,日,程序能计算并输出该日在本年中是第几天。注意润年问题。

2.      运用链表实现电话簿管理:设计一个基本电话簿管理程序,具有加入、删除和显示联系人电话号码的功能。程序要求采用链表数据结构来实现。


/*******第七章,第01题
定义一个结构体变量(包括年,月,日)编写程序,要求输入年,月,日,
程序能计算并输出该日在本年中是第几天。注意润年问题。
*****************************************************************/

#include <iostream>
using namespace std;

struct date
{
private:
	int year;
	int month;
	int day;
public:
	void input();
	int deal1();
};


void date::input()
{
	cout<< "请输入年,月,日,并用空格间开:";
	cin >> year >> month >> day;
	cout<< endl;
}

int date::deal1()
	{
		//先用if断断是不是1月和2月的
		//再用if判断是不是润年
		//后用确定2月份的天数后,后面的天数可以直接加上
		/*判断每个月份的天数
		31天的月份有:1.3.5.7.8.10.12
		30天的月份有:4.6.9.11
		28或29天的月份有:2
		*/
		
		int n;						//设定n为总天数
		static int n2;
		int d = day;
		
		//31天的
		static int n31 = 31;
		int& n1 = n31;	int& n3 = n31;	int& n5 = n31;
		int& n7 = n31;	int& n8 = n31;	int& n10 = n31;
		int& n12 = n31;

		//30天的
		static int n30 = 30;
		int& n4 = n30;	int& n6 = n30;	int& n9 = n30;
		int& n11 = n30;

		//开始计算
		if ( (month==1)||(month==2) )
		{
			if (month==1) 
				{
				n = d;
				return n;
				}
			if (month==2) 
				{
				n = n1+d;
				return n;
				}
		}
		else
		{
			if (year%4==0&&year%100!=0)
				n2 = 29;
			else
				n2 = 28;
			switch(month)
			{
			case 3 : n = n1+n2+d; break;
			case 4 : n = n1+n2+n3+d; break;
			case 5 : n = n1+n2+n3+n4+d; break;
			case 6 : n = n1+n2+n3+n4+n5+d; break;
			case 7 : n = n1+n2+n3+n4+n5+n6+d; break;
			case 8 : n = n1+n2+n3+n4+n5+n6+n7+d; break;
			case 9 : n = n1+n2+n3+n4+n5+n6+n7+n8+d; break;
			case 10 : n = n1+n2+n3+n4+n5+n6+n7+n8+n9+d; break;
			case 11 : n = n1+n2+n3+n4+n5+n6+n7+n8+n9+n10+d; break;
			case 12 : n = n1+n2+n3+n4+n5+n6+n7+n8+n9+n10+n11+d; break;
			}
		}
	return n;
}

void main()
{
	typedef date time;	//本句没什么必要用,写出这句是因为想试一下用typedef
	time e;
	date* p;
	p = &e;
	
	(*p).input();
	(*p).deal1();

	int n = (*p).deal1();
	cout<< "该日在本年中是第 " << n << "天" <<endl; 
}



/*********链表
运用链表实现电话簿管理:
设计一个基本电话簿管理程序,具有加入、删除和显示联系人电话号码的功能。
程序要求采用链表数据结构来实现。
***********************************/

//问题一:输入N个电话号码,输出的只是N-1个号码
//已解决问题一:将for里面的判断条件改为  pz!=NULL
//问题二:add 函数出现问题。需调试。
//已解决:改了循环的条件,再改了结点的位置,了解到了一点,->next就是该地址的下一地址。


#define NULL 0
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

struct telephone_directory			//定义电话簿结构类型
{
	string name;					//联系人姓名
	long num;						//电话号码
	telephone_directory* next;		//结点
};
typedef telephone_directory td;		//用typedef声明,指定用td代表telephone_directory类型
long n = 0;							//电话簿的内容中的序号

/**** 主函数  **/
/**** 主函数  **/
void main(void)
{
/*************************  定义+声明 ********************************/
	td *creat(void);				//创建(函数声明)
	td *insert(td *,string, int);	//加入(函数声明)
	td *del(td*,string);			//删除(函数声明)
	td *show(td*);					//显示(函数声明)

	td *head;						//定义头指针
	td tda;							//定义这个电话簿的一个变量
	string dname;					//定义删除的联系人名称

/*************************  输入 ********************************/
	cout << "请输入联系人姓名和联系电话:(输入“数字0”结束输入)" << endl;
	cout << "序号" << setw(8) << "姓名" << setw(8) << "电话" <<endl;
	head = creat();					//返回头指针
	show(head);						//输出电话簿
/*************************  删除 ********************************/
	cout << "请输入要删除的联系电话的姓名:" ;
	cin >> dname;
	cout << endl;
	head = del(head,dname);			//删除后链表的头地址
	show(head);						//输出电话簿
/*************************  加入 ********************************/
	cout << "请输入要加入联系人的姓名及电话号码:" ;
	string nname;int nnum;			//定义一个需加入的姓名,电话。
	cin >> nname >>nnum;
	cout << endl;
	head = insert(head, nname, nnum);//加入后链表的地址
	show(head);						//输出电话簿
}

/****  建立链表的函数,返回头指针  ***/
/****  建立链表的函数,返回头指针  ***/
td *creat(void)
{
	td *head;						//定义头文件及两个指针
	td *pa;
	td *pb;
	
	pa = new td;					//开辟一个新单元(建立第一个结点),并使pa指向它
	cout << ++n << setw(3) <<":";        //输入序号
	cin >> pa->name ;
	cin >> pa->num;
	cout << endl;
/*生成头结点;while(未结束){ 生成新结点;  把新结点插入链表;}*/
	head = NULL;					//生成头结点(链表头指针初始化)
	for ( n=2; pa->num!=0 ; n++)//向链表插新结点
	{
		if (head==NULL)
			head = pa;
		else 
			pb->next = pa;			//指向本结点
		pb = pa;
		pa = new td;				//生成新结点
		cout << n << setw(3) <<":";	//输入数据
		cin >> pa->name ;
		cin >> pa->num;
		cout << endl;
	}
	pb->next = NULL;				//
	delete pa;						//释放值为0的结点
	return (head);					//返回头指针
}

/*********建立一个 删除 结点的函数*************************/
/*********建立一个 删除 结点的函数*************************/
td *del(td *head,string dname)
{
	if (head==NULL)					//是空表
		{
		cout << "这是一个空的电话薄,无法删除" <<endl;
		return (head);
		}
	else
	{
	td *pa;
	td *pb;
	pa = head;						//使pa指向第一个结点
	for (;dname!=pa->name && pa->next!=NULL;)//pa所指向的不是要找的结点且不是最后一个结点
		{
		pb = pa;
		pa = pa->next;
		}
	if ( dname==pa->name )			//假如找到了要删的名字
		if ( pa==head )
			head = pa->next;		//若pa是首地址,则将下一个地址赋予head
		else
		{
		pb->next = pa->next;	//否则,将下一结点地址赋予上一结点地址
		cout << "删除成功!" << endl;
		}
	else
		cout << "电话簿中找不到" << dname << "这联系人" << endl;
	}
	return (head);
}

/*************** 建立新结点的函数 ******************/
/*************** 建立新结点的函数 ******************/
td *insert(td * head,string nname, int nnum)
{
	td *pa;
	td *pb;
	for (pa=head; pa->next!=NULL; pa= pa->next);//找到最后结点
	pb = new td;							//新建一个结点
	pa->next = pb;							//连接两个结点
	pb->name = nname;						//赋值
	pb->num = nnum;
	pb->next = NULL;
	return(head);
}

/********  按序排列并输出电话簿(此处先不排序)  *******/
td *show(td *head)
{
	td *pz ;
	pz = head;
	cout << "您输入的电话簿经整理后:" << endl ;
	cout << "序号" << setw(8) << "姓名" << setw(8) << "电话" <<endl;
	for (n=1; pz!=NULL; n++)
	{
		cout << n << setw(3) << pz->name << setw(8) << pz->num << endl;
		pz = pz->next;						//让指针结点指向下一个
	}
return(NULL);
}


#include <string>
#include <iostream>
#include <cstdio>

using namespace std;

typedef struct tel
{
        string name;
        string number;

        tel *next;
}TEL;

//root为链表的头指针
TEL *root = NULL;

char menu()
{        
        cout << "--------" << endl;
        cout << "1,登记" << endl;
        cout << "2,删除" << endl;
        cout << "3,查询" << endl;
        cout << "4,列表" << endl;
        cout << "0,退出" << endl;
        cout << "--------" << endl;
        cout << "请选择:";

        char choice;
        cin >> choice;

        cout << endl;

        return choice;
}
//从文件加载数据,未实现
TEL* load()
{
        return NULL;
}

//把数据保存到文件,未实现
int save()
{
        return 0;
}

//登记
void reg()
{
        //获取数据

        string name;

        while(name.empty())
        {
                cout << "请输入姓名:";
                cin >> name;
        }

        string number;
        while(number.empty())
        {
                cout << "请输入号码:";
                cin >> number;
        }

        //分配新结点
        TEL* t = new TEL;

        t->next = NULL;
        t->name = name;
        t->number = number;
        
        //如果root指针为空,则直接赋值root
        if(root == NULL)
        {
                root = t;
        }
        else
        {
                //找到最后一个结点,并使它指向新的结点
                TEL* p = root;
                while(p->next != NULL)
                        p = p->next;

                p->next = t;
        }

}

//显示结点数据
void show(TEL* t)
{
        cout << t->name << '\t' << t->number << endl;
}

//删除
//采用的方法是:遍历root链表,模糊找查并提供用户是否删除。
//如果用户确认删除当前结点,则移动指针到下个结点继续上面的过程
//如果当前结点无须删除,则将他移动到新的链表中
//最后,将root指向新的链表的第一个结点
void del()
{
        cout << "请输入:"; 
        string some;
        cin >> some;


        //p1指向root,移动p1指针,遍历root
        TEL* p1 = root;

        //new_root为新链表的头指针
        TEL* new_root = NULL;
        //p2指向新链表的最后一个结点
        TEL* p2 = NULL;

        while(p1 != NULL)
        {
                if(p1->name.find(some) != string::npos ||
                        p1->number.find(some) != string::npos)
                {
                        show(p1);

                        cout << "确定删除(y/n):";
                        char c;
                        cin >> c;
                        //找到符合条件的结点,让用户确认删除
                        if(c == 'y')
                        {
                                TEL* temp = p1->next;
                                delete p1;

                                p1 = temp;
                                continue;
                        }
                }

                if(new_root == NULL)
                {
                        new_root = p1;
                        p1 = p1->next;

                        p2 = new_root;
                        p2->next = NULL;
                        
                }
                else
                {
                        p2->next = p1;
                        p1 = p1->next;

                        p2 = p2->next;
                        p2->next = NULL;
                }
        }

        root = new_root;

}

//查询
void query()
{
        string some;
        cout << "请输入:";

        cin >> some;

        TEL* p = root;
        while(p != NULL)
        {
                if(p->name.find(some) != string::npos ||
                        p->number.find(some) != string::npos)

                        show(p);

                p = p->next;
        }

}

//列表
void list()
{
        TEL* p = root;
        int i = 0;
        cout << "姓名\t号码\t" << endl;
        while(p != NULL)
        {
                show(p);
                p = p->next;
        }
}


int main()
{
        root = load();
        do
        {
                char c = menu();

                switch(c)
                {
                case '1'://登记
                        reg();
                        break;

                case '2'://删除
                        del();
                        break;

                case '3'://查询
                        query();
                        break;

                case '4'://列表
                        list();
                        break;

                case '0':
                        {
                                int total_saved = save();
                                cout << total_saved << "items saved." << endl;
                                
                                exit(0);
                        }

                        break;

                default:
                        break;
                }

        }while(true);


        return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值