已有带头结点循环单链表存储结构定义如下: typedef struct node{ /*结点类型定义*/ DataType data; /结点的数据域*/ struct node *next; /*结点的指针域*/ }ListNode, *LinkList; 设计一个算法,将首元结点摘下链接到终端结点之后成为新的终端结点,而原来的第二个结点成为新的开始结点,返回新链表的头指针。 LinkList Demo(LinkList L) { //L为带头结点的单链表
时间: 2023-05-19 12:03:46 浏览: 111
以下是算法实现:
LinkList Demo(LinkList L) {
if (L == NULL || L->next == NULL) {
return L;
}
ListNode *p = L->next;
ListNode *q = p->next;
while (q->next != L) {
q = q->next;
}
q->next = p;
L->next = q;
p->next = NULL;
return L->next;
}
解释一下算法的思路:
首先判断链表是否为空或只有一个结点,如果是,直接返回原链表头指针。
定义两个指针 p 和 q,分别指向原链表的第一个和第二个结点。
遍历链表,找到终端结点 q。
将终端结点 q 的 next 指针指向首元结点 p。
将头结点 L 的 next 指针指向终端结点 q。
将首元结点 p 的 next 指针置为 NULL。
返回新链表的头指针 L->next。
注意:这个算法只适用于带头结点的循环单链表。如果是普通的单链表,需要先将尾结点找到,然后再进行操作。
相关问题
C++用单链表为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的手机号、及电子邮箱。其功能包括通讯录链表的建立、员工通讯信息的查询、修改、插入与删除、以及整个通讯录表的输出。 操作分为查询、修改、添加、删除、打印 1. 查询:输入员工姓名,输出员工信息,若员工不存在,输出“NOT FOUND!” 2. 修改:输入员工姓名、要修改的属性,修改信息。姓名为name、电话为tel、邮箱为mail。 3. 添加:输入员工编号、姓名、电话号码、邮箱。 4. 删除:输入员工姓名,将其从通讯录中删除。 5. 打印:输出通讯录。用到存储结构: typedef struct { /*员工通讯信息的结构类型定义*/ char num[5]; /*员工编号*/ char name[10]; /*员工姓名*/ char tel[15]; /*办公室电话号码*/ char call[15]; /*手机号码*/ char mail[25]; /*邮箱*/ }DataType; /*通讯录单链表的结点类型*/ typedef struct node { DataType data; /*结点的数据域*/ struct node *next; /*结点的指针域*/ }ListNode,*LinkList;代码
以下是基本实现代码,可以根据需要进行修改和完善:
```c++
#include <iostream>
#include <cstring>
using namespace std;
typedef struct {
char num[5];
char name[10];
char tel[15];
char call[15];
char mail[25];
} DataType;
typedef struct node {
DataType data;
struct node *next;
} ListNode, *LinkList;
// 创建通讯录链表
LinkList createList() {
LinkList head = new ListNode;
head->next = NULL;
return head;
}
// 添加员工信息
void insertNode(LinkList L, DataType data) {
ListNode *p = new ListNode;
p->data = data;
p->next = L->next;
L->next = p;
}
// 查询员工信息
void searchNode(LinkList L, char name[]) {
ListNode *p = L->next;
while (p != NULL) {
if (strcmp(p->data.name, name) == 0) {
cout << "编号:" << p->data.num << endl;
cout << "姓名:" << p->data.name << endl;
cout << "电话:" << p->data.tel << endl;
cout << "手机:" << p->data.call << endl;
cout << "邮箱:" << p->data.mail << endl;
return;
}
p = p->next;
}
cout << "NOT FOUND!" << endl;
}
// 修改员工信息
void modifyNode(LinkList L, char name[], char field[], char value[]) {
ListNode *p = L->next;
while (p != NULL) {
if (strcmp(p->data.name, name) == 0) {
if (strcmp(field, "name") == 0) {
strcpy(p->data.name, value);
} else if (strcmp(field, "tel") == 0) {
strcpy(p->data.tel, value);
} else if (strcmp(field, "call") == 0) {
strcpy(p->data.call, value);
} else if (strcmp(field, "mail") == 0) {
strcpy(p->data.mail, value);
} else {
cout << "Invalid field!" << endl;
return;
}
cout << "Modify succeed!" << endl;
return;
}
p = p->next;
}
cout << "NOT FOUND!" << endl;
}
// 删除员工信息
void deleteNode(LinkList L, char name[]) {
ListNode *p = L->next, *pre = L;
while (p != NULL) {
if (strcmp(p->data.name, name) == 0) {
pre->next = p->next;
delete(p);
cout << "Delete succeed!" << endl;
return;
}
pre = p;
p = p->next;
}
cout << "NOT FOUND!" << endl;
}
// 输出通讯录
void printList(LinkList L) {
ListNode *p = L->next;
while (p != NULL) {
cout << "编号:" << p->data.num << endl;
cout << "姓名:" << p->data.name << endl;
cout << "电话:" << p->data.tel << endl;
cout << "手机:" << p->data.call << endl;
cout << "邮箱:" << p->data.mail << endl;
p = p->next;
}
}
int main() {
LinkList L = createList();
int choice;
char name[10];
char field[10];
char value[25];
DataType data;
while (true) {
cout << "1.查询 2.修改 3.添加 4.删除 5.打印 0.退出" << endl;
cin >> choice;
if (choice == 0) {
break;
}
switch (choice) {
case 1:
cout << "请输入员工姓名:";
cin >> name;
searchNode(L, name);
break;
case 2:
cout << "请输入员工姓名:";
cin >> name;
cout << "请输入要修改的属性(name/tel/call/mail):";
cin >> field;
cout << "请输入新值:";
cin >> value;
modifyNode(L, name, field, value);
break;
case 3:
cout << "请输入员工编号、姓名、电话、手机、邮箱:";
cin >> data.num >> data.name >> data.tel >> data.call >> data.mail;
insertNode(L, data);
cout << "Add succeed!" << endl;
break;
case 4:
cout << "请输入员工姓名:";
cin >> name;
deleteNode(L, name);
break;
case 5:
printList(L);
break;
default:
cout << "Invalid choice!" << endl;
break;
}
}
return 0;
}
```
1. 单位员工通讯录管理系统(线性表) [题目描述] 为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的手机号、及电子邮箱。其功能包括通讯录链表的建立、员工通讯信息的查询、修改、插入与删除、以及整个通讯录表的输出。 操作分为查询、修改、添加、删除、打印 1. 查询:输入员工姓名,输出员工信息,若员工不存在,输出“NOT FOUND!” 2. 修改:输入员工姓名、要修改的属性,修改信息。姓名为name、电话为tel、邮箱为mail。 3. 添加:输入员工编号、姓名、电话号码、邮箱。 4. 删除:输入员工姓名,将其从通讯录中删除。 5. 打印:输出通讯录。 [实现提示] 可以采用单链表的存储结构,如可定义如下的存储结构: typedef struct { /*员工通讯信息的结构类型定义*/ char num[5]; /*员工编号*/ char name[10]; /*员工姓名*/ char tel[15]; /*办公室电话号码*/ char call[15]; /*手机号码*/ char mail[25]; /*邮箱*/ }DataType; /*通讯录单链表的结点类型*/ typedef struct node { DataType data; /*结点的数据域*/ struct node *next; /*结点的指针域*/ }ListNode,*LinkList;用c语言
下面是一个简单的实现,具体实现细节可以根据需求进行调整:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUM 5
#define MAX_NAME 10
#define MAX_TEL 15
#define MAX_CALL 15
#define MAX_MAIL 25
// 定义员工通讯信息的结构类型
typedef struct {
char num[MAX_NUM]; // 员工编号
char name[MAX_NAME]; // 员工姓名
char tel[MAX_TEL]; // 办公室电话号码
char call[MAX_CALL]; // 手机号码
char mail[MAX_MAIL]; // 邮箱
} DataType;
// 定义通讯录单链表的结点类型
typedef struct node {
DataType data; // 结点的数据域
struct node* next; // 结点的指针域
} ListNode, *LinkList;
// 初始化通讯录
void init(LinkList* list) {
*list = (ListNode*) malloc(sizeof(ListNode));
(*list)->next = NULL;
}
// 查询员工信息
void search(LinkList list) {
char name[MAX_NAME];
printf("请输入员工姓名:");
scanf("%s", name);
ListNode* p = list->next;
while (p != NULL) {
if (strcmp(p->data.name, name) == 0) {
printf("员工编号:%s\n", p->data.num);
printf("员工姓名:%s\n", p->data.name);
printf("办公室电话号码:%s\n", p->data.tel);
printf("手机号码:%s\n", p->data.call);
printf("邮箱:%s\n", p->data.mail);
return;
}
p = p->next;
}
printf("NOT FOUND!\n");
}
// 修改员工信息
void modify(LinkList list) {
char name[MAX_NAME];
char attr[MAX_NAME];
char value[MAX_NAME];
printf("请输入员工姓名:");
scanf("%s", name);
printf("请输入要修改的属性(name/tel/call/mail):");
scanf("%s", attr);
printf("请输入新的值:");
scanf("%s", value);
ListNode* p = list->next;
while (p != NULL) {
if (strcmp(p->data.name, name) == 0) {
if (strcmp(attr, "name") == 0) {
strcpy(p->data.name, value);
} else if (strcmp(attr, "tel") == 0) {
strcpy(p->data.tel, value);
} else if (strcmp(attr, "call") == 0) {
strcpy(p->data.call, value);
} else if (strcmp(attr, "mail") == 0) {
strcpy(p->data.mail, value);
} else {
printf("无效的属性!\n");
}
printf("修改成功!\n");
return;
}
p = p->next;
}
printf("NOT FOUND!\n");
}
// 添加员工信息
void add(LinkList list) {
ListNode* p = list;
while (p->next != NULL) {
p = p->next;
}
ListNode* newNode = (ListNode*) malloc(sizeof(ListNode));
printf("请输入员工编号:");
scanf("%s", newNode->data.num);
printf("请输入员工姓名:");
scanf("%s", newNode->data.name);
printf("请输入办公室电话号码:");
scanf("%s", newNode->data.tel);
printf("请输入手机号码:");
scanf("%s", newNode->data.call);
printf("请输入邮箱:");
scanf("%s", newNode->data.mail);
newNode->next = NULL;
p->next = newNode;
printf("添加成功!\n");
}
// 删除员工信息
void remove(LinkList list) {
char name[MAX_NAME];
printf("请输入员工姓名:");
scanf("%s", name);
ListNode* p = list->next;
ListNode* pre = list;
while (p != NULL) {
if (strcmp(p->data.name, name) == 0) {
pre->next = p->next;
free(p);
printf("删除成功!\n");
return;
}
pre = p;
p = p->next;
}
printf("NOT FOUND!\n");
}
// 输出通讯录
void print(LinkList list) {
ListNode* p = list->next;
while (p != NULL) {
printf("员工编号:%s\n", p->data.num);
printf("员工姓名:%s\n", p->data.name);
printf("办公室电话号码:%s\n", p->data.tel);
printf("手机号码:%s\n", p->data.call);
printf("邮箱:%s\n", p->data.mail);
p = p->next;
}
}
int main() {
LinkList list;
init(&list);
int choice;
do {
printf("\n");
printf("1. 查询员工信息\n");
printf("2. 修改员工信息\n");
printf("3. 添加员工信息\n");
printf("4. 删除员工信息\n");
printf("5. 输出通讯录\n");
printf("0. 退出\n");
printf("请输入你的选择:");
scanf("%d", &choice);
switch (choice) {
case 1:
search(list);
break;
case 2:
modify(list);
break;
case 3:
add(list);
break;
case 4:
remove(list);
break;
case 5:
print(list);
break;
case 0:
break;
default:
printf("无效的选择!\n");
break;
}
} while (choice != 0);
return 0;
}
```
注意在删除员工信息时,需要用一个指针 pre 来记录当前结点的前一个结点,以便在删除结点时修改前一个结点的指针域。
阅读全文