void menu()
{
printf("**********************************************************\n");
printf("1數(shù)據(jù)的創(chuàng)建 \t2數(shù)據(jù)的插入\t3數(shù)據(jù)的刪除\n4數(shù)據(jù)的更改\t5求數(shù)據(jù)最大值\t6數(shù)據(jù)的排序\n7輸出數(shù)據(jù)\t8退出\t\
9清屏\n");
printf("********************************************************\n");
}
#二、每個(gè)函數(shù)的簡(jiǎn)紹與思路
##1:密碼登錄的驗(yàn)證思路:
(1)在主函數(shù)main里定義一個(gè)標(biāo)志 flat2=0;如果flat2!=0,就代表密碼登錄成功,可以進(jìn)入系統(tǒng)!
(2)在具體函數(shù)mima()之中,使用了控制臺(tái)函數(shù)_getch();其頭文件為#include<conio.h>,該函數(shù)可以隱藏輸出,注意:_getch()是隱藏單個(gè)字符,且需要一個(gè)存儲(chǔ)空間,可以使用數(shù)組結(jié)合循環(huán)來使用,例子a[i]=_getch();此時(shí)在終端上不會(huì)顯示內(nèi)容,所以結(jié)合printf語(yǔ)句讓用戶明白我們輸入的多少!并且加入判斷,回車是結(jié)束輸入的功能并且給此時(shí)空間賦值一個(gè)’\0’!
定義一個(gè)j是保證最大的失誤范圍若超過系統(tǒng)退出!
(3)刪除功能是:當(dāng)輸入回車時(shí),阻止繼續(xù)輸入*,(使用continue);,并且給此時(shí)空間賦值一個(gè)’\0’,
在進(jìn)行printf(“\b”);鼠標(biāo)箭頭回退,printf(" “);輸入空格覆蓋 “*”;在讓鼠標(biāo)回退printf(”\b");
代碼如下
void mima(int* flag2)
{
int j = 6;
char mima[20];
int i = 0;
while (1)
{
i = 0;
printf("請(qǐng)輸入用戶名:");
char name[16];
scanf("%s", name);
printf("請(qǐng)輸入密碼:");
while (1)
{
mima[i] = _getch();
if (mima[i] == '\r')
{
mima[i] = '\0';
break;
}
else if (mima[i] == '\b')
{
mima[i] = '\0';
printf("\b");
printf(" ");
printf("\b");
i--;
continue;
}
else
{
printf("*");
i++;
if (i == 19)
{
printf("密碼已達(dá)到最大長(zhǎng)度!\n");
break;
}
}
}
if (strcmp(name, "小明") == 0)
{
if (strcmp(mima, "2082716421") == 0)
{
*flag2 = 2;
printf("輸入正確!\n");
break;
}
else
{
j--;
printf("賬戶或密碼錯(cuò)誤!\n");
printf("你還有%d次機(jī)會(huì)\n", j);
if (j == 0)
{
printf("已達(dá)到輸入密碼最多次數(shù)\n");
break;
}
}
}
else
{
j--;
printf("查詢不到用戶!\n");
printf("你還有%d次機(jī)會(huì)\n", j);
if (j == 0)
{
printf("已達(dá)到輸入密碼最多次數(shù)\n");
break;
}
}
}
}
##創(chuàng)建鏈表
使用了一個(gè)單鏈表,鏈表思路如下:
(1)首先創(chuàng)建一個(gè)結(jié)構(gòu)體;
typedef struct Date
{
int age[6];
char name[16];
int length;
}lp;//創(chuàng)建這個(gè)結(jié)構(gòu)體是為了高效進(jìn)行數(shù)據(jù)域交換的冒泡排序
typedef struct student
{
lp data;
struct student *next;
}Lp;(注意一般結(jié)構(gòu)體里是不許賦初值的)
頭節(jié)點(diǎn)head(這個(gè)是大基,不要?jiǎng)铀院蟮牟僮骱瘮?shù)傳它,用它去進(jìn)行插入,刪除,輸出等功能)且數(shù)據(jù)域不要存放東西,因?yàn)楹罄m(xù)插入等操作要用到!,賦值鏈節(jié)p,p=head;新鏈節(jié) q(指針);開辟他的空間,并使用p->next=q;在讓p=q;q在去開辟空間重復(fù)上述功能!
注意的是,如果在函數(shù)內(nèi)開辟空間,涉及到函數(shù)傳參問題
思路1:使用函數(shù)指針且返回的是頭節(jié)點(diǎn)。
Lp* Creatlist(Lp* head)
{
head = (Lp*)malloc(sizeof(Lp));//頭節(jié)點(diǎn)不要在數(shù)據(jù)域存數(shù)據(jù)
Lp* p = head, * q = NULL;
head->data.length = 0;//確定鏈表的長(zhǎng)度
while (1)
{
q = (Lp*)malloc(sizeof(Lp));
p->next = q;
p = q;
printf("請(qǐng)輸入%d位學(xué)生姓名:", head->data.length + 1);
scanf("%s", p->data.name);
if (strcmp(p->data.name, "結(jié)束輸入") == 0)
{
break;
}
printf("請(qǐng)輸入%d位學(xué)生六科成績(jī):", head->data.length + 1);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
head->data.length++;
}
p->next = NULL;
return head;
}
思路2: 傳二級(jí)指針對(duì)一級(jí)指針的修改。
void creatlianbiao(ch** head, int* a)
{
*a = 0;//檢驗(yàn)鏈接的長(zhǎng)度
*head = (ch*)malloc(sizeof(ch));//開辟鏈表頭的空間
ch* p = NULL, * q = NULL;
p = *head;
while (1)
{
printf("請(qǐng)輸入姓名:");
scanf("%s", p->a.name);
if (strcmp(p->a.name, "退出") == 0)
{
break;
}
printf("請(qǐng)輸入成績(jī):");
scanf("%d", & p->a.cj);
(*a)++;
q = (ch*)malloc(sizeof(ch));
p->next = q;
p = q;
}
p->next = NULL;
}
//思路如此,這個(gè)是一個(gè)姓名對(duì)應(yīng)一個(gè)值
//這個(gè)沒有插入等操作所以為了省空間頭節(jié)點(diǎn)數(shù)據(jù)域存放了數(shù)據(jù)
##檢驗(yàn)鏈表的開辟是否成功(遍歷鏈表)
主要思路就是當(dāng)p->next==NULL時(shí),跳出循環(huán);
void Outputlist(Lp* head)
{
Lp* p; p = head->next;//頭節(jié)點(diǎn)沒有數(shù)據(jù)所以是head->next;
while (p->next != NULL)
{
printf("%s:\t", p->data.name);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
printf("%d\t", p->data.a[i]);
}
printf("\n");
p = p->next;
}
}
##3插入與刪除,改變鏈表功能
思路:這三者基本一樣,區(qū)別的是:插入需要找到目標(biāo)后對(duì)其后或之前進(jìn)行插入(會(huì)導(dǎo)致首節(jié)點(diǎn),或末節(jié)點(diǎn)插入有些許困難),刪除就是找到目標(biāo)位置進(jìn)行指針跳過這個(gè)指向后一節(jié)操作!而改變是在找到目標(biāo)情況下進(jìn)行修改具體如下
(1)插入:采用了查詢姓名+首個(gè)成績(jī)來找值,并在其后進(jìn)行操作,這里分別給出插入某個(gè)人數(shù)據(jù)后面的和首位置得方法
Lp* Insertmenu(Lp* head)
{
int a=0;
Lp* Insertlist(Lp * head);
Lp* Inserfirsttlist(Lp * head);
void Outputlist(Lp * head);//聲明函數(shù)
printf("***************************\n");
printf("1,插入首位\t2插入某個(gè)人數(shù)據(jù)后面\t3退出\t4輸出\n");
while (a != 888)
{
printf("請(qǐng)輸入你要選擇插入的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Inserfirsttlist(head); break;
case 2:head = Insertlist(head); break;
case 3: a = 888;//退出循環(huán)條件
break;
case 4:Outputlist(head); break;
default:printf("請(qǐng)輸入1—4的數(shù)據(jù)"); break;
}
}
return head;
}
//插入鏈?zhǔn)椎?/span>
Lp* Inserfirsttlist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)先初始化在進(jìn)行其他操作");
return head;
}//判斷是否初始化創(chuàng)建鏈表
printf("你進(jìn)入的是插入首鏈節(jié)選擇!\n");
Lp* p, * q;
Lp* m = head->next;//存放首個(gè)數(shù)據(jù)域的節(jié)點(diǎn)
p = head;
q = (Lp*)malloc(sizeof(Lp));//開辟空間
printf("請(qǐng)輸入插入的學(xué)生姓名:");
scanf("%s", q->data.name);
printf("請(qǐng)輸入%該學(xué)生六科成績(jī):");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//測(cè)長(zhǎng)度
p->next = q;
q->next = m;
return head;
}
//插入某個(gè)數(shù)據(jù)的后面的
Lp* Insertlist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)初始化在進(jìn)行其他操作!");
return head;
}//檢驗(yàn)是否位為空條件
char name[16];
int a;
printf("請(qǐng)輸入要插入那個(gè)人的姓名+首個(gè)成績(jī):");
scanf("%s", name);
scanf("%d", &a);
Lp* p = head->next, * q;//頭節(jié)點(diǎn)為指針域?yàn)榭?/span>
Lp* m = head->next->next;//緊跟著存放p的后繼位!方便插入
int k = 0;//檢驗(yàn)是否找到數(shù)據(jù)
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("已成功找到要插入數(shù)據(jù)\n");
q = (Lp*)malloc(sizeof(Lp));
printf("請(qǐng)輸入學(xué)生姓名:");
scanf("%s", q->data.name);
printf("請(qǐng)輸入學(xué)生六科成績(jī):");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//長(zhǎng)度
p->next = q;
q->next = m;
k++;
break;//找到后直接跳出循環(huán)
}
else
{
p = p->next;
m = m->next;
}//保持鏈表向后進(jìn)行
}
if (k == 0)
{
printf("未找到數(shù)據(jù)\n");
}
return head;
}
(2)刪除(其實(shí)可以寫一個(gè)函數(shù)完成,但是為了對(duì)稱采用此方法)
Lp* Deletemenu(Lp* head)
{
void Outputlist(Lp * head);//聲明
int a = 0;
printf("***************************\n");
printf("1,刪除首位\t2刪除某個(gè)人數(shù)據(jù)后面\t3退出\t4輸出\n");
while (a != 888)
{
printf("請(qǐng)輸入你要選擇刪除的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Deletefirstlist(head); break;
case 2:head = Deletelist(head); break;
case 3: a = 888;//退出循環(huán)條件
break;
case 4:Outputlist(head); break;
default:printf("請(qǐng)輸入1—4的數(shù)據(jù)"); break;
}
}
return head;
}
Lp* Deletefirstlist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)先初始化在進(jìn)行其他操作");
return head;
}//判斷是否初始化創(chuàng)建鏈表
Lp* p = head;//用來跳過首個(gè)有數(shù)據(jù)的鏈結(jié)
Lp* q = head->next->next;//注意這里不在是開辟空間啦,這是有數(shù)據(jù)的鏈結(jié)后的鏈結(jié)
p->next = q;
head->data.length--;
return head;
}
Lp* Deletelist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)先初始化在進(jìn)行其他操作");
return head;
}//判斷是否初始化創(chuàng)建鏈表
Lp* p = head;
Lp* q = head->next;//p后的鏈結(jié)
printf("請(qǐng)輸入要插入那個(gè)人的姓名+首個(gè)成績(jī):");
char name[16];
int a;
int k = 0;//檢驗(yàn)是否找到數(shù)據(jù)
scanf("%s", name);
scanf("%d", &a);
while (p->next != NULL)
{
if (strcmp(q->data.name, name) == 0 && q->data.a[0] == a)//這里不能用p->next來因?yàn)闊o法對(duì)目標(biāo)數(shù)據(jù)進(jìn)行處理
{
printf("已成功找到要插入數(shù)據(jù)\n");
p ->next = q->next;
k++;
head->data.length--;
break;
}
else
{
p = p->next;
q = q->next;
}
}
if (k == 0)
{
printf("未找到數(shù)據(jù)\n");
}
return head;
}
(3)改變鏈表數(shù)據(jù)(查到目標(biāo)數(shù)據(jù)進(jìn)行修改,可以借鑒這個(gè)進(jìn)行另一種刪除)
Lp* Chooselist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)初始化在進(jìn)行其他功能!");
return head;
}
Lp* p = head->next;
printf("請(qǐng)輸入你要修改學(xué)生的姓名+首個(gè)成績(jī):");
char name[16];
scanf("%s", name);
int a;
scanf("%d", &a);
int k = 0;
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("查詢到你要修改的數(shù)據(jù)\n");
printf("請(qǐng)輸出要修改的數(shù)據(jù)的姓名:");
scanf("%s", p->data.name);
printf("請(qǐng)輸入學(xué)生六科成績(jī):");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
break;
}
else
{
p = p->next;
}
}
return head;
}
##求最值問題(按照總分大小進(jìn)行比,但是寫的是average不要介意呦?。?/p>
因?yàn)樵谂判蛑幸玫娇傊岛瘮?shù)所以設(shè)立兩個(gè)函數(shù)!
注意:一定要給average賦初值(當(dāng)時(shí)一直以為是排序問題,沒想到出錯(cuò)在這)
Lp* Maxlist(Lp* head)
{
//這里在結(jié)構(gòu)體里加了一個(gè) int average 來進(jìn)行比較
Lp* p = head->next;//因?yàn)轭^節(jié)點(diǎn)數(shù)據(jù)域?yàn)榭?/span>
while (p->next != NULL)
{
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
p->data.average += p->data.a[i];
}
p = p->next;
}
return head;
}
void Maxoutput(Lp* head)
{
Lp* p;
p = head->next;
Lp *max=NULL;
max = p;
while (p->next != NULL)
{
if (p->data.average > max->data.average)
{
max = p;
}
p = p->next;
}
printf("%s:", max->data.name);
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
printf("%d\n", max->data.a[i]);
}
printf("\n");
}
##排序問題?。。ǚ?,折騰我這么長(zhǎng)時(shí)間)
排序算法(1,是進(jìn)行數(shù)據(jù)域的交換,2是指針域的交換)
1數(shù)據(jù)域交換的思路:(采用的冒泡,這里區(qū)別的是在交換數(shù)據(jù),直接把節(jié)點(diǎn)的數(shù)據(jù)域進(jìn)行交換,推薦兩個(gè)結(jié)構(gòu)體)原來排序是i<n-1;這里直接改成p->next->next != NULL,并且內(nèi)循環(huán)是q->next->next!=NULL;相比于下標(biāo)這里沒有了每次在內(nèi)循環(huán)減一操作,
也可以用下標(biāo)法,這里我們長(zhǎng)度已經(jīng)給了,亦可以用,(下標(biāo)法沒寫,這個(gè)簡(jiǎn)單)
兩者區(qū)別是:一個(gè)需要長(zhǎng)度,另一個(gè)不需要長(zhǎng)度
2:指針域交換的思路:我們已經(jīng)測(cè)量了長(zhǎng)度,就可以避免了q->NULL的交換了,這里我們交換不是設(shè)置中間變量的簡(jiǎn)單交換,例如p=head->next;q=p->next;交換后要寫成,p->next=q->next;
q->next=p;!不推薦使用臨時(shí)變量去交換!
因?yàn)閜 和q 在動(dòng),我們要在往后遍歷時(shí)推薦設(shè)一個(gè)第三方變量 move并且由move去引導(dǎo)進(jìn)行兩兩相鄰的比較!
3總結(jié):指針域交換適合數(shù)據(jù)域非常大的時(shí)候,數(shù)據(jù)域交換適合數(shù)據(jù)域較少的因?yàn)樯婕暗綌?shù)據(jù)域的拷貝
Lp* Sortkaozhilist(Lp* head)
{
printf("按照平均分從小到大的寫法且按照拷貝數(shù)據(jù)域方法進(jìn)行\(zhòng)n");
Lp* Maxlist(Lp * head);//聲明
head = Maxlist(head);
Lp* p = head->next;//控制外循環(huán)
Lp* q = head->next;//控制內(nèi)循環(huán)
for (; p->next->next != NULL; p = p->next)
{
for (q=head->next;q->next->next != NULL; q = q->next)//這樣寫有個(gè)不好的,這是是全部進(jìn)行比較,不是每次少一個(gè)但是這樣寫的好處是不用測(cè)量長(zhǎng)度!在數(shù)據(jù)少這樣寫的快
//這里我想了想設(shè)立了一個(gè)下標(biāo)操作!這樣寫的好處是不用測(cè)量長(zhǎng)度!
{
if (q->next != NULL || q != NULL)//防止越界
{
if (q->data.average > q->next->data.average)
{
lp t;//作為中間變量進(jìn)行替換
t = q->data;
q->data = q->next->data;
q->next->data = t;
}
}
}
}
return head;
}
Lp* Sortzhizhenlist(Lp* head)
{
printf("進(jìn)行的是指針域的改變按照從大到小(適合大數(shù)據(jù))\n");
printf("并且是下標(biāo)法的冒泡排序\n");
printf("請(qǐng)檢驗(yàn)下標(biāo)的數(shù)據(jù)為:%d\n", head->data.length);
Lp* Maxlist(Lp * head);//聲明函數(shù)
head = Maxlist(head);
Lp* p = head->next;
Lp* q = head->next->next;//p的后節(jié)點(diǎn)
Lp* move=head;//因?yàn)閜和q指針域發(fā)生變化,所以需要用move去遍歷
for (int i = 0; i < head->data.length-1; i++)
{
p = head->next;
q = p->next;
move = head;//初始化
for (int j = 0; j < head->data.length - 1 - i; j++)
{
if (p->data.average <q->data.average)
{
p->next = q->next;//把p后面那個(gè)節(jié)點(diǎn)的指針域給p->next;
q->next = p;//原本時(shí)p指向q,現(xiàn)在是q指向p
move->next = q;//找到要移動(dòng)的位置
}//交換相鄰指針域使最少的放在后面;
move = move->next;//這樣是每次往后進(jìn)行相鄰比較
p = move->next;
q = p->next;//往后移
}
}
return head;
}
Lp* sortmenu(Lp* head)
{
void Outputlist(Lp * head);//聲明
int a = 0;
printf("***************************\n");
printf("1拷貝值排序(適合數(shù)據(jù)小的)\t2指針域排序(有點(diǎn)不同)\t3退出\t4輸出\n");
while (a != 888)
{
printf("請(qǐng)輸入你要選擇排序的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Sortkaozhilist(head); break;
case 2:head = Sortzhizhenlist(head); break;
case 3: a = 888;//退出循環(huán)條件
break;
case 4:Outputlist(head); break;
default:printf("請(qǐng)輸入1—4的數(shù)據(jù)"); break;
}
}
return head;
}
##可運(yùn)行總代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-856008.html
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
typedef struct Data
{
int a[6];
char name[16];
int average;
int length;
}lp;//創(chuàng)建這個(gè)結(jié)構(gòu)體是為了高效進(jìn)行冒泡排序
typedef struct student
{
lp data;
struct student* next;
}Lp;
void mima(int* flag2)
{
int j = 6;
char mima[20];
int i = 0;
while (1)
{
i = 0;
printf("請(qǐng)輸入用戶名:");
char name[16];
scanf("%s", name);
printf("請(qǐng)輸入密碼:");
while (1)
{
mima[i] = _getch();
if (mima[i] == '\r')
{
mima[i] = '\0';
break;
}
else if (mima[i] == '\b')
{
mima[i] = '\0';
printf("\b");
printf(" ");
printf("\b");
i--;
continue;
}
else
{
printf("*");
i++;
if (i == 19)
{
printf("密碼已達(dá)到最大長(zhǎng)度!\n");
break;
}
}
}
if (strcmp(name, "小明") == 0)
{
if (strcmp(mima, "2082716421") == 0)
{
*flag2 = 2;
printf("輸入正確!\n");
break;
}
else
{
j--;
printf("賬戶或密碼錯(cuò)誤!\n");
printf("你還有%d次機(jī)會(huì)\n", j);
if (j == 0)
{
printf("已達(dá)到輸入密碼最多次數(shù)\n");
break;
}
}
}
else
{
j--;
printf("查詢不到用戶!\n");
printf("你還有%d次機(jī)會(huì)\n", j);
if (j == 0)
{
printf("已達(dá)到輸入密碼最多次數(shù)\n");
break;
}
}
}
}
void menu()
{
printf("**********************************************************\n");
printf("1數(shù)據(jù)的創(chuàng)建 \t2數(shù)據(jù)的插入\t3數(shù)據(jù)的刪除\n4數(shù)據(jù)的更改\t5求數(shù)據(jù)最大值\t6數(shù)據(jù)的排序\n7輸出數(shù)據(jù)\t8退出\t\
9清屏\n");
printf("********************************************************\n");
}
Lp* Creatlist(Lp* head)
{
head = (Lp*)malloc(sizeof(Lp));//頭節(jié)點(diǎn)不要在數(shù)據(jù)域存數(shù)據(jù)
Lp* p = head, * q = NULL;
head->data.length = 0;//確定鏈表的長(zhǎng)度
while (1)
{
q = (Lp*)malloc(sizeof(Lp));
p->next = q;
p = q;
printf("請(qǐng)輸入%d位學(xué)生姓名:", head->data.length + 1);
scanf("%s", p->data.name);
if (strcmp(p->data.name, "結(jié)束輸入") == 0)
{
break;
}
printf("請(qǐng)輸入%d位學(xué)生六科成績(jī):", head->data.length + 1);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
head->data.length++;
}
p->next = NULL;
return head;
}
Lp* Insertmenu(Lp* head)
{
int a=0;
Lp* Insertlist(Lp * head);
Lp* Inserfirsttlist(Lp * head);
void Outputlist(Lp * head);//聲明函數(shù)
printf("***************************\n");
printf("1,插入首位\t2插入某個(gè)人數(shù)據(jù)后面\t3退出\t4輸出\n");
while (a != 888)
{
printf("請(qǐng)輸入你要選擇插入的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Inserfirsttlist(head); break;
case 2:head = Insertlist(head); break;
case 3: a = 888;//退出循環(huán)條件
break;
case 4:Outputlist(head); break;
default:printf("請(qǐng)輸入1—4的數(shù)據(jù)"); break;
}
}
return head;
}
Lp* Inserfirsttlist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)先初始化在進(jìn)行其他操作");
return head;
}//判斷是否初始化創(chuàng)建鏈表
printf("你進(jìn)入的是插入首鏈節(jié)選擇!\n");
Lp* p, * q;
Lp* m = head->next;//存放首個(gè)數(shù)據(jù)域的節(jié)點(diǎn)
p = head;
q = (Lp*)malloc(sizeof(Lp));//開辟空間
printf("請(qǐng)輸入插入的學(xué)生姓名:");
scanf("%s", q->data.name);
printf("請(qǐng)輸入%該學(xué)生六科成績(jī):");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//測(cè)長(zhǎng)度
p->next = q;
q->next = m;
return head;
}
Lp* Insertlist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)初始化在進(jìn)行其他操作!");
return head;
}//檢驗(yàn)是否位為空條件
char name[16];
int a;
printf("請(qǐng)輸入要插入那個(gè)人的姓名+首個(gè)成績(jī):");
scanf("%s", name);
scanf("%d", &a);
Lp* p = head->next, * q;//頭節(jié)點(diǎn)為指針域?yàn)榭?/span>
Lp* m = head->next->next;//緊跟著存放p的后繼位!方便插入
int k = 0;//檢驗(yàn)是否找到數(shù)據(jù)
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("已成功找到要插入數(shù)據(jù)\n");
q = (Lp*)malloc(sizeof(Lp));
printf("請(qǐng)輸入學(xué)生姓名:");
scanf("%s", q->data.name);
printf("請(qǐng)輸入學(xué)生六科成績(jī):");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &q->data.a[i]);
}
head->data.length++;//長(zhǎng)度
p->next = q;
q->next = m;
k++;
break;//找到后直接跳出循環(huán)
}
else
{
p = p->next;
m = m->next;
}//保持鏈表向后進(jìn)行
}
if (k == 0)
{
printf("未找到數(shù)據(jù)\n");
}
return head;
}
Lp* Deletelist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)先初始化在進(jìn)行其他操作");
return head;
}//判斷是否初始化創(chuàng)建鏈表
Lp* p = head;
Lp* q = head->next;//p后的鏈結(jié)
printf("請(qǐng)輸入要插入那個(gè)人的姓名+首個(gè)成績(jī):");
char name[16];
int a;
int k = 0;//檢驗(yàn)是否找到數(shù)據(jù)
scanf("%s", name);
scanf("%d", &a);
while (p->next != NULL)
{
if (strcmp(q->data.name, name) == 0 && q->data.a[0] == a)//這里不能用p->next來因?yàn)闊o法對(duì)目標(biāo)數(shù)據(jù)進(jìn)行處理
{
printf("已成功找到要插入數(shù)據(jù)\n");
p ->next = q->next;
k++;
head->data.length--;
break;
}
else
{
p = p->next;
q = q->next;
}
}
if (k == 0)
{
printf("未找到數(shù)據(jù)\n");
}
return head;
}
Lp* Deletefirstlist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)先初始化在進(jìn)行其他操作");
return head;
}//判斷是否初始化創(chuàng)建鏈表
Lp* p = head;//用來跳過首個(gè)有數(shù)據(jù)的鏈結(jié)
Lp* q = head->next->next;//注意這里不在是開辟空間啦,這是有數(shù)據(jù)的鏈結(jié)后的鏈結(jié)
p->next = q;
head->data.length--;
return head;
}
Lp* Deletemenu(Lp* head)
{
void Outputlist(Lp * head);//聲明
int a = 0;
printf("***************************\n");
printf("1,刪除首位\t2刪除某個(gè)人數(shù)據(jù)后面\t3退出\t4輸出\n");
while (a != 888)
{
printf("請(qǐng)輸入你要選擇刪除的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Deletefirstlist(head); break;
case 2:head = Deletelist(head); break;
case 3: a = 888;//退出循環(huán)條件
break;
case 4:Outputlist(head); break;
default:printf("請(qǐng)輸入1—4的數(shù)據(jù)"); break;
}
}
return head;
}
Lp* Chooselist(Lp* head)
{
if (head == NULL)
{
printf("請(qǐng)初始化在進(jìn)行其他功能!");
return head;
}
Lp* p = head->next;
printf("請(qǐng)輸入你要修改學(xué)生的姓名+首個(gè)成績(jī):");
char name[16];
scanf("%s", name);
int a;
scanf("%d", &a);
int k = 0;
while (p->next != NULL)
{
if (strcmp(p->data.name, name) == 0 && p->data.a[0] == a)
{
printf("查詢到你要修改的數(shù)據(jù)\n");
printf("請(qǐng)輸出要修改的數(shù)據(jù)的姓名:");
scanf("%s", p->data.name);
printf("請(qǐng)輸入學(xué)生六科成績(jī):");
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
scanf("%d", &p->data.a[i]);
}
break;
}
else
{
p = p->next;
}
}
return head;
}
Lp* Sortkaozhilist(Lp* head)
{
printf("按照平均分從小到大的寫法且按照拷貝數(shù)據(jù)域方法進(jìn)行\(zhòng)n");
Lp* Maxlist(Lp * head);//聲明
head = Maxlist(head);
Lp* p = head->next;//控制外循環(huán)
Lp* q = head->next;//控制內(nèi)循環(huán)
for (; p->next->next != NULL; p = p->next)
{
for (q=head->next;q->next->next != NULL; q = q->next)//這樣寫有個(gè)不好的,這是是全部進(jìn)行比較,不是每次少一個(gè)但是這樣寫的好處是不用測(cè)量長(zhǎng)度!在數(shù)據(jù)少這樣寫的快
//這里我想了想設(shè)立了一個(gè)下標(biāo)操作!這樣寫的好處是不用測(cè)量長(zhǎng)度!
{
if (q->next != NULL || q != NULL)//防止越界
{
if (q->data.average > q->next->data.average)
{
lp t;//作為中間變量進(jìn)行替換
t = q->data;
q->data = q->next->data;
q->next->data = t;
}
}
}
}
return head;
}
Lp* Sortzhizhenlist(Lp* head)
{
printf("進(jìn)行的是指針域的改變按照從大到小(適合大數(shù)據(jù))\n");
printf("并且是下標(biāo)法的冒泡排序\n");
printf("請(qǐng)檢驗(yàn)下標(biāo)的數(shù)據(jù)為:%d\n", head->data.length);
Lp* Maxlist(Lp * head);//聲明函數(shù)
head = Maxlist(head);
Lp* p = head->next;
Lp* q = head->next->next;//p的后節(jié)點(diǎn)
Lp* move=head;//因?yàn)閜和q指針域發(fā)生變化,所以需要用move去遍歷
for (int i = 0; i < head->data.length-1; i++)
{
p = head->next;
q = p->next;
move = head;//初始化
for (int j = 0; j < head->data.length - 1 - i; j++)
{
if (p->data.average <q->data.average)
{
p->next = q->next;//把p后面那個(gè)節(jié)點(diǎn)的指針域給p->next;
q->next = p;//原本時(shí)p指向q,現(xiàn)在是q指向p
move->next = q;//找到要移動(dòng)的位置
}//交換相鄰指針域使最少的放在后面;
move = move->next;//這樣是每次往后進(jìn)行相鄰比較
p = move->next;
q = p->next;//往后移
}
}
return head;
}
Lp* sortmenu(Lp* head)
{
void Outputlist(Lp * head);//聲明
int a = 0;
printf("***************************\n");
printf("1拷貝值排序(適合數(shù)據(jù)小的)\t2指針域排序(有點(diǎn)不同)\t3退出\t4輸出\n");
while (a != 888)
{
printf("請(qǐng)輸入你要選擇排序的功能:");
scanf("%d", &a);
switch (a)
{
case 1:head = Sortkaozhilist(head); break;
case 2:head = Sortzhizhenlist(head); break;
case 3: a = 888;//退出循環(huán)條件
break;
case 4:Outputlist(head); break;
default:printf("請(qǐng)輸入1—4的數(shù)據(jù)"); break;
}
}
return head;
}
Lp* Maxlist(Lp* head)
{
//這里在結(jié)構(gòu)體里加了一個(gè) int average 來進(jìn)行比較
Lp* p = head->next;//因?yàn)轭^節(jié)點(diǎn)數(shù)據(jù)域?yàn)榭?/span>
while (p->next != NULL)
{
//這里給p->data.average賦初值;
p->data.average = 0;
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
p->data.average += p->data.a[i];
}
p = p->next;
}
return head;
}
void Maxoutput(Lp* head)
{
Lp* p;
p = head->next;
Lp *max=NULL;
max = p;
while (p->next != NULL)
{
if (p->data.average > max->data.average)
{
max = p;
}
p = p->next;
}
printf("%s:", max->data.name);
for (int i = 0; i < sizeof(p->data.a) / sizeof(p->data.a[0]); i++)
{
printf("%d\n", max->data.a[i]);
}
printf("\n");
}
void Outputlist(Lp* head)
{
Lp* p; p = head->next;//頭節(jié)點(diǎn)沒有數(shù)據(jù)所以是head->next;
while (p->next != NULL)
{
printf("%s:\t", p->data.name);
for (int i = 0; i < sizeof(head->data.a) / sizeof(head->data.a[0]); i++)
{
printf("%d\t", p->data.a[i]);
}
printf("\n");
p = p->next;
}
}
int main()
{
//為了數(shù)據(jù)的檢驗(yàn)方便沒有設(shè)置及時(shí)清屏功能,請(qǐng)見諒
int flag2 = 0;//檢驗(yàn)密碼登錄系統(tǒng)的正確行
/*mima(&flag2);*/
flag2 = 1;
Lp* head = NULL;
if (flag2 != 0)
{
int Tc = 0;//選擇菜單的退出
menu();
int choose = 0;//菜單選擇的變量
while (Tc == 0)
{
printf("請(qǐng)選擇功能:");
scanf("%d", &choose);
switch (choose)
{
case 1:head = Creatlist(head); break;
case 2: head = Insertmenu(head); break;
case 3:head = Deletemenu(head); break;
case 4:head = Chooselist(head); break;
case 6:head = sortmenu(head); break;
case 5:if (head = Maxlist(head))Maxoutput(head);break;
case 7:Outputlist(head); break;
case 8:Tc = 1; break;
case 9:system("cls"); system("pause"); menu(); break;
default:printf("請(qǐng)輸入1—9選擇功能");
}
}
}
return 0;
}
##學(xué)習(xí)之作
此為學(xué)習(xí)上的見解,若有錯(cuò)誤或不同理解歡迎大家的批評(píng)與改正(第一次寫,排版可能有問題,請(qǐng)見諒)文章來源地址http://www.zghlxwxcb.cn/news/detail-856008.html
到了這里,關(guān)于在c語(yǔ)言中使用鏈表完成學(xué)生成績(jī)管理系統(tǒng)(密碼登錄系統(tǒng)的采納,加入了隱藏與刪除功能,添加了指針域與數(shù)據(jù)域兩種不同的排序)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!