建立的是一个有序的管理学生信息的双向链表,功能有创建,插入,删除, 遍历, 查找等。
#include <iostream>
#include <string>
using namespace std;
typedef long long LL;
struct List{
int num;
string name;
LL tel;
struct List * prior;
struct List * next;
};
List *Insert(List *head, List *tmp); // 插入函数声明
List *create()
{
List *head, *p; // 头结点和待插入节点
int num;
string name;
LL tel;
head = NULL; // 头结点初始为空
cout << "input num, name and tel: \n";
cin >> num >> name >> tel;
while(num) // 输入编号为0退出
{
p = new List;
p->num = num;
p->name = name;
p->tel = tel;
head = Insert(head, p); // 调用插入函数插入新节点
cin >> num >> name >> tel;
}
return head; // 返回创建的链表的头结点的地址
}
List *Insert(List *head, List *tmp)
{
List *ptr, *ptr1, *ptr2; // 定义辅助指针
ptr2 = head; // 初始 ptr2 指向头结点
ptr = tmp; // 初始 ptr 是指向待插入节点
if(head == NULL) // 如果头结点还为空
{
head = ptr; // 头结点为待插入结点
head->prior = NULL; // 前驱也为NULL
head->next = NULL; // 因为此时还没有下一个节点,所以head->next 为空
}
else // 如果头结点不为空
{ // 寻找带插入结点应该插入的位置,链表的顺序是num从小到达的顺序
while((ptr->num > ptr2->num) && (ptr2->next != NULL))
{
ptr1 = ptr2; // ptr1 是 ptr2 的前驱结点
ptr2 = ptr2->next; // ptr2 后移
}
if(ptr->num <= ptr2->num)
{
if(head == ptr2) // ptr2是头结点
{
head = ptr; // 插入到头结点前面,头结点前移
head->prior = NULL; // 头结点前没有结点了
head->next = ptr2; // 新的头结点的后继
ptr2->prior = head; // 下一个结点的前驱
ptr2->next =NULL; // 后继没有结点了
}
else // 插入在两个结点的中间
{
ptr1->next = ptr;
ptr->prior = ptr1;
}
ptr->next = ptr2;
ptr2->prior = ptr;
}
else // 插入在末尾
{
ptr2->next = ptr;
ptr->prior = ptr2;
ptr->next = NULL;
}
}
return head;
}
List *Delete(List *head, int num)
{
List *ptr1, *ptr2; // 辅助指针
while(head != NULL && head->num == num)
{
ptr2 = head;
head = head->next; // 头结点后移
head->prior = NULL;
delete ptr2; // 删除之前的头结点
}
if(head == NULL) // 如果没有节点
return NULL;
ptr1 = head;
ptr2 = head->next;
while(ptr2 != NULL)
{
if(ptr2->num == num)
{
ptr1->next = ptr2->next;
if(ptr2->next != NULL) // 如果是最后一个结点则不能执行这一步
ptr2->next->prior = ptr1;
// ptr2->next->prior = ptr2->prior;
delete ptr2;
}
else
ptr1 = ptr2;
ptr2 = ptr1->next;
}
return head;
}
void Print(List *head) // 遍历输出函数
{
List *ptr;
if(head == NULL)
{
cout << endl << "No Records" << endl;
return;
}
cout << "num\t name\t tel\n";
ptr = head;
while(ptr != NULL)
{
cout << ptr->num << "\t ";
cout << ptr->name << "\t ";
cout << ptr->tel << endl;
ptr = ptr->next;
}
}
List *Find(List *head, int num)
{
List *flag = NULL;
for(List *ptr = head; ptr != NULL; ptr = ptr->next)
{
if(ptr->num == num)
{
flag = ptr;
}
}
return flag;
}
int main()
{
List *head, *p;
int num;
string name;
LL tel;
int choice;
do{
cout << "1: create\n2: insert\n3: delete\n4: print\n5: Find\n0: exit\n";
cin >> choice;
switch(choice)
{
case 1:
head = create();
break;
case 2:
cout << "input num, name and tel: \n";
cin >> num >> name >> tel;
p = new List;
p->num = num;
p->name = name;
p->tel = tel;
head = Insert(head, p);
break;
case 3:
cout << "input num" << endl;
cin >> num;
head = Delete(head, num);
break;
case 4:
Print(head);
break;
case 5:
cin >> num;
List * ptr = Find(head, num);
if(ptr != NULL)
{
if(ptr->prior != NULL) // 如果有前驱结点,输出前驱的人的名字
cout << ptr->prior->name << endl;
cout << ptr->name << "\t ";
cout << ptr->tel << endl;
}
else
cout << "No Find" << endl;
}
}while(choice != 0);
return 0;
}