c語言順序表按順序存儲
1. 在C語言中,寫出二維數組元素a[2][3]在內存中的存放順序
在 C 語言中,二維數組是由一系列連續的內存位置組成的,其中每個元素佔用一個特定的位元組數。對於一個二維數組 a[2][3],其存放順序如下圖所示:
```
+------+------+------+
| a[0][0] | a[0][1] | a[0][2] |
+------+------+------+
| a[1][0] | a[1][1] | a[1][2] |
+------+------+------+
```
在這個示例中,我們定義了一個 2 行 3 列的二維數組 `a`。對於每個元素,它的值都存儲在內存中的一個特定地址上。可以看到,第一行的元素 `a[0][0]`、`a[0][1]` 和 `a[0][2]` 存儲在連續的內存位置中,接著是第二行的元素 `a[1][0]`、`a[1][1]` 和 `a[1][2]`。
對於這個示例中的二維數組而言,如果使用指針訪問它們,則需要將其視為一個一維數組來處理。具體來說,可以將二維數組轉��為一個指向包含所有元素的一維數組的指針,並使用單個索引來訪問每個元素。例如,要訪問 `a[1][2]` 的值,可以使用以下代碼:
```c
int a[2][3];
int *p;
p = &a[0][0]; // 將二維數組轉換為一維數組指針
*(p + 1*3 + 2) = 42; // 訪問 a[1][2] 並將其賦值為 42
```
在這個示例中,我們首先定義了一個 2 行 3 列的二維數組 `a`。然後,我們使用指針 `p` 將二維數組轉換為一維數組的指針。最後,我們使用 `(p + 1*3 + 2)` 計算出 `a[1][2]` 在數組中的偏移量,並將其值設置為 42。注意,這里的 「偏移量」 是指此元素與數組起始位置之間的距離,以位元組為單位計算。
2. 是C語言中建立順序表的程序
C語言中建立順序表的操作順序如下:
1.清空順序表:其實清空只不過將元素長度置0,讓後面插入數據函數的長度從0開始,其實並不是真正清空,之前的數據元素在內存中還存在,只不過可以被新元素覆蓋而已。
2.判斷順序表是否為空
3. 用C語言實現線性表的順序存儲(創建,插入,刪除和查找)
//C++課程設計---學生成績管理系統
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <stdlib.h>
#include <windows.h>
typedef struct studentinfo //結構體定義
{
int num;//學號
char name[64];//姓名
int sex;//性別,1為男性,0為女性
float math;//數學
float english;//英語
float politic;//政治
float chinese;//語文
float total;//總成績
struct studentinfo *next;
}STUDENT;
#define FILENAME "D:\\1.txt"
//定義默認的資料庫文件
#define DELAYTIME 1500
//顯示信息,延時
void create_menu();
STUDENT * new_student();
STUDENT* create_linkbyfile(char *);
STUDENT *del_info(STUDENT *);
int save_info(char *,STUDENT *,int);
int find_infile_printf(char *);
int pri_whole_link(STUDENT *);
STUDENT* printf_sort(STUDENT *);
void free_link(STUDENT *);
void main() //主函數
{
create_menu();
}
STUDENT * reverse(STUDENT *head)
//功能:鏈表反轉順序
//參數:head鏈表頭結點指針
{
STUDENT *ptemp,*p1;
if(head==NULL)
{
return 0;
}
p1=head;//p1使之永遠指向排好序的第一個結點,初值為head,head使之永遠是已經排好序的最後一個結點
while(head->next!=NULL)//本次循環使ptemp排好序
{
ptemp=head->next;//ptemp指向未排好序的第一個結點
head->next=ptemp->next;//
ptemp->next=p1;//ptemp也排好序了,ptemp變成排好序的第一個結點了
p1=ptemp;//再次讓p1成為第一個排好序的結點
}
return p1;//頭結點為第一個結點
}
void create_menu()
//功能:輸出功能菜單,提供人-機介面
{
char menu_Num;
STUDENT *head=NULL;
char ch;
char file_name[256];
while(1)
{
system("cls");
cout<<"\t\t學生成績管理系統\n";
cout<<"##########################################\n";
cout<<"#\t\t 1.新增學生信息\t\t #\n";
cout<<"#\t\t 2.載入資料庫\t\t #\n";
cout<<"#\t\t 3.刪除學生信息\t\t #\n";
cout<<"#\t\t 4.保存學生信息\t\t #\n";
cout<<"#\t\t 5.資料庫查詢\t\t #\n";
cout<<"#\t\t 6.原序輸出\t\t #\n";
cout<<"#\t\t 7.排序輸出\t\t #\n";
cout<<"#\t\t 8.退出\t\t\t #\n";
cout<<"##########################################\n";
cout<<"請輸入操作編號:";
cin>>menu_Num;
switch (menu_Num)
{
case '1':
free_link(head);//釋放鏈表空間
head=new_student();//新增學生信息
break;
case '2':
free_link(head);//釋放鏈表空間
cout<<"請輸入要載入的資料庫文件的路徑"<<endl;
cin>>file_name;
head=create_linkbyfile(file_name);//讀取數據文件
if(head!=NULL)
{
cout<<"資料庫"<<file_name<<"已載入"<<endl;
Sleep(DELAYTIME);
}
break;
case '3':
del_info(head);//刪除學生信息
break;
case '4'://保存學生信息
if (head==NULL)
{
cout<<"請先生成學生信息"<<endl;
Sleep(DELAYTIME);
}
else
{
cout<<"想將學生信息保存到哪個資料庫文件?";
cin>>file_name;
cout<<"請選擇保存方式:0追加到文件末尾 1覆蓋文件\n";
cin>>menu_Num;
if(save_info(file_name,head,menu_Num-'0')==0)//0表示追加,1表示覆蓋
{
cout<<"信息保存失敗\n";
}
else
{
cout<<"數據已保存到"<<file_name<<endl;
Sleep(DELAYTIME);
}
}
break;
case '5':
find_infile_printf(FILENAME);//資料庫查詢
break;
case '6'://原序輸出信息
pri_whole_link(head);
cout<<"返回主菜單? Y/N\t";
do
{
cin>>ch;
}while(ch!='Y'&&ch!='y');
break;
case '7'://排序輸出信息
do
{
if((head=printf_sort(head))==NULL)
{
cout<<"資料庫未載入"<<endl;
Sleep(DELAYTIME);
break;
}
else
{
cout<<"選擇其他方式排序? Y/N\t";
cin>>ch;
}
}while(ch=='Y'||ch=='y');
break;
case '8':
free_link(head);//釋放鏈表空間
exit(0);
break;
default:
cout<<"輸入有誤!請重新輸入!"<<endl;
Sleep(DELAYTIME);
break;
}
}
}
STUDENT * new_student()
//功能:創建學生信息(通過鏈表)
//返回值:頭結點指針
{
STUDENT *pnew,*p,*head;
float *pfloat;
char ch;
head=NULL;
do
{
system("cls");
pnew=(STUDENT *)malloc(sizeof(STUDENT)*1);
cout<<"請輸入學生的學號(0表示取消): ";
cin>>pnew->num;
if(0>=pnew->num)
{
break;
}
cout<<"請輸入學生的姓名:";
cin>>pnew->name;
while(1)
{
cout<<"請輸入學生的性別:0/1\t";
cin>>pnew->sex;
if(pnew->sex&&pnew->sex-1)
{
cout<<"性別輸入錯誤,0表示女性,1表示男性,請重新輸入"<<endl;
}
else
{
break;
}
}
cout<<"請依次輸入學生的數學、英語、政治、語文成績:"<<endl;
for(pnew->total=0,pfloat=&pnew->math;pfloat<&pnew->math+4;)
{
cin>>*pfloat;
if(*pfloat<0||*pfloat>150)
{
cout<<"成績輸入錯誤,只能為0~150"<<endl;
}
else
{
pnew->total+=*pfloat;
pfloat++;
}
}
if(head==NULL)
{
head=pnew;
}
else
{
p->next=pnew;
}
p=pnew;
pnew->next=NULL;
cout<<"##########################該學生信息已生成#########################\n";
cout<<"建立另一個學生的信息? Y/N\t";
cin>>ch;
}while(ch=='Y'||ch=='y');
return head;
}
STUDENT* create_linkbyfile(char *filename)
//功能:讀取文件,創建鏈表
//參數:如果filename不為空,則打開該文件,如果filename為空,要求輸入文件位置
//創建的鏈表的所有結點的next全部修改,指向物理地址上的下一個結點
{
system("cls");
FILE *fp;
STUDENT *head,*ptemp,*pnew;
head=NULL;//初始化head為空
if(filename==NULL)//若filename為空,要求輸入文件絕對地址
{
char file_name[256];
cout<<"請輸入資料庫文件的路徑:"<<endl;
cin>>file_name;
if(NULL==(fp=fopen(file_name,"rb")))
{
cout<<"資料庫連接失敗\n";
return 0;
}
}
else
{
if(NULL==(fp=fopen(filename,"rb")))
{
cout<<"資料庫連接失敗\n";
return 0;
}
}
for(ptemp=NULL;;)
{
pnew=(STUDENT *)malloc(sizeof(STUDENT)*1);
if(fread(pnew,sizeof(STUDENT),1,fp)!=NULL)
{
if(ptemp!=NULL)
{
ptemp->next=pnew;
}
else
{
head=pnew;
}
ptemp=pnew;
}
else
{
if(ptemp!=NULL)
{
ptemp->next=NULL;
}
else
{
head=NULL;
}
free(pnew);
break;
}
}
fclose(fp);
return head;
}
STUDENT *del_info(STUDENT *head)
//根據學號,刪除鏈表的結點
{
system("cls");
STUDENT *p1,*p2;
int num;
if (head==NULL)
{
cout<<"資料庫未載入"<<endl;
Sleep(DELAYTIME);
return 0;
}
cout<<"請輸入要刪除學生的學號:";
cin>>num;
for(p1=head;p1!=NULL;)
{
if(p1->num==num)//找到
{
if(p1==head)//要刪除的結點是頭結點
{
head=p1->next;
}
else
{
p2->next=p1->next;
}
cout<<"成功刪除!!";
}
p2=p1;
p1=p1->next;
}
return head;
}
int save_info(char *filename,STUDENT *head,int flag)
//功能:將鏈表按Binary寫入文件末尾
//參數:
//1.filename文件名,絕對地址
//2.head指向鏈表的頭結點
//3.flag 0追加或1覆蓋數據
//返回值:失敗則返回0
{
system("cls");
FILE *fp;
STUDENT *p;
char openmethod[8];
if(flag==0)
{
strcpy(openmethod,"ab+");//追加
}
else
{
strcpy(openmethod,"w");//覆蓋
}
if(NULL==(fp=fopen(filename,openmethod)))//
{
cout<<"資料庫連接失敗"<<endl;
Sleep(DELAYTIME);
return 0;
}
else
{
for(p=head;p;p=p->next)
{
if((fwrite(p,sizeof(STUDENT),1,fp))==NULL)
{
cout<<"資料庫創建失敗"<<endl;
return 0;
}
}
}
fclose(fp);
return 1;
}
int find_infile_printf(char *filename)
//功能:根據學號和姓名來查詢某個學生
//參數:filename資料庫文件
//返回值:失敗返回0
//直接搜索文件,缺點是速度慢
//也可先根據文件創建鏈表,再搜索鏈表,缺點是如果文件較大,佔用內存多
{
system("cls");
FILE *fp;
STUDENT stu;
int num;
char stu_name[64];
char ch;
if(filename==NULL)
{
return 0;
}
do
{
memset(stu_name,0,sizeof(stu_name));
cout<<"查詢學號或查詢姓名? 1查詢學號 0查詢姓名";
//flag=1根據學號來查詢,flag=0根據姓名來查詢
cin>>num;
if(num==1)
{
cout<<"輸入要查詢的學號:";
cin>>num;
cout<<"正在為您查詢學號為"<<num<<"的學生……"<<endl;
}
else if(num==0)
{
cout<<"輸入要查詢的姓名:";
cin>>stu_name;
cout<<"正在為您查詢姓名為"<<stu_name<<"的學生……"<<endl;
}
else
{
cout<<"輸入有誤"<<endl;
return 0;
}
if(NULL==(fp=fopen(filename,"rw")))
{
cout<<"資料庫連接失敗\n";
return 0;
}
else
{
while(fread(&stu,sizeof(STUDENT),1,fp)!=NULL)
{
if(strcmp(stu.name,stu_name)==0||stu.num==num)
{
cout<<"學號\t姓名\t性別\t數學\t英語\t政治\t語文\t總成績\n";
//輸出該學生的所有信息
cout<<stu.num<<"\t"<<stu.name<<"\t"<<stu.sex<<"\t"<<stu.math<<"\t"<<stu.english<<"\t"<<stu.politic<<"\t"<<stu.chinese<<"\t"<<stu.total<<endl;
//不加break;可支持多個相同數據的索引
}
}
}
cout<<"##########################查詢完畢#########################\n";
cout<<"查詢另一個學生的信息? Y/N\t";
cin>>ch;
}while(ch=='Y'||ch=='y');
fclose(fp);
return 1;
}
int pri_whole_link(STUDENT *head)
//功能:顯示整條鏈表的學生信息
//參數:head 頭結點指針,如果head為空,返回空
{
system("cls");
STUDENT* p;
if (head==NULL)
{
cout<<"資料庫未載入"<<endl;
Sleep(DELAYTIME);
return 0;
}
cout<<"學號\t姓名\t性別\t數學\t英語\t政治\t語文\t總成績\n";
for(p=head;p;p=p->next)
{
cout<<p->num<<"\t"<<p->name<<"\t"<<p->sex<<"\t"<<p->math<<"\t"<<p->english<<"\t"<<p->politic<<"\t"<<p->chinese<<"\t"<<p->total<<endl;
}
return 1;
}
STUDENT* printf_sort(STUDENT *head)
//功能:根據學號|某科目成績|總成績對鏈表進行排序,然後輸出
//參數:head鏈表頭指針,如果head為空,返回空
//返回值:返回新的鏈表的頭結點指針
{
system("cls");
STUDENT *p1,*p2,*ptemp,*pfinished=NULL;
char num;
char flag;
if (head==NULL)
{
return 0;
}
cout<<"選擇排序依據 0.數學成績1.英語成績2.政治成績3.語文成績4.總成績\n";
while(1)
{
cin>>num;
if(num>'4'||num<'0')
{
cout<<"輸入有誤,請重新輸入 0~4"<<endl;
}
else
{
break;
}
}
cout<<"升序/降序輸出? 0.降序1.升序";
while(1)
{
cin>>flag;
if(flag>'1'||flag<'0')
{
cout<<"輸入有誤,請重新輸入 0~1"<<endl;
}
else
{
break;
}
}
for(p1=head;p1->next!=pfinished;)//對鏈表進行從大到小排序(這里用冒泡法)
//p1使之總是指向頭結點,pfinished使之總是指向已排序好的最前面的結點
//ptemp作為中介,保存p2的上一個結點
{
for(p2=p1;p2->next!=pfinished;)
{
if(*(&(p2->math)+num-'0')<*(&(p2->next->math)+num-'0'))//p2的值小於p2->next的值,交換 ptemp p2 p2->next
{
if(p2==p1)//頭結點要交換
{
p1=p2->next;
p2->next=p1->next;
p1->next=p2;
ptemp=p1;
}
else
{
ptemp->next=p2->next;
ptemp=p2->next;
p2->next=ptemp->next;
ptemp->next=p2;
}
}
else//不需要交換,則p2、ptemp前進1位
{
ptemp=p2;
p2=p2->next;
}
}
pfinished=p2;
}
if(flag=='1')
{
p1=reverse(p1);
}
pri_whole_link(p1);
cout<<"##########################信息顯示完畢#########################\n";
return p1;
}
void free_link(STUDENT *head)
//釋放鏈表空間,如果head,什麼都不做
{
STUDENT *p1,*p2;
for(p1=head;p1;p1=p2)
{
p2=p1->next;//先保存,否則
free(p1);//free後 p1->next數據丟失
}
}
4. 如何建立一個順序存儲的線性表,實現線性表的插入、刪除操作
順序存儲結構線性表基本操作 C語言實現
#include<stdio.h>
//以下為函數運行結果狀態代碼
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2
#defineLIST_INIT_SIZE100//線性表存儲空間的初始分配量
#defineLISTINCREMENT10//線性表存儲空間分配增量
typedefintStatus;//函數類型,其值為為函數結果狀態代碼
typedefintElemType;//假設數據元素為整型
typedefstruct
{
ElemType*elem;//存畢碰儲空間基址
intlength;//當前長度
intlistsize;//當前分配的存儲容量
}SqList;
//實現線性表的順序存儲結嫌譽構的類型定義
//函數聲明開手者談始
StatusInitList_Sq(SqList&L);
voidDestroyList_Sq(SqList&L);
voidClearList_Sq(SqList&L);
voidListEmpty_Sq(SqListL);
StatusGetElem_Sq(SqListL,i,&e);
intLocateElem_Sq(SqListL,e,compare());
StatusPriorElem_Sq(SqListL,cur_e,&pre_e);
StatusNextElem_Sq(SqListL,cur_e,&next_e);
StatusListInsert_Sq(SqList&L,i,e);
StatusListDelete_Sq(SqList&L,i,&e);
ListTravel_Sq(SqListL,visit());
//函數聲明結束
intmain(void)
{
return0;
}
//函數定義開始
///////////////////////////////////////
//函數名:InitList_Sq()
//參數:SqList*L
//初始條件:無
//功能:構造一個空線性表
//返回值:存儲分配失敗:OVERFLOW
//存儲分配成功:OK
///////////////////////////////////////
StatusInitList_Sq(SqList*L)
{
L.elem=(ElemType*)malloc((LIST_INIT_SIZE*sizeof(ElemType));//分配空間
if(!L.elem)
exit(OVERFLOW);//若存儲分配失敗,返回OVERFLOW
L.length=0;//空表,長度為0
L.listsize=LIST_INIT_SIZE;//初始存儲容量
returnOK;
}
///////////////////////////////////////
//函數名:DestroyList_Sq()
//參數:SqList*L
//初始條件:線性表L已存在
//功能:銷毀線性表
//返回值:無
///////////////////////////////////////
voidDestroyList_Sq(SqList*L)
{
if(L->elem)
free(L->elem);//釋放線性表占據的所有存儲空間
}
///////////////////////////////////////
//函數名:ClearList_Sq()
//參數:SqList*L
//初始條件:線性表L已存在
//功能:清空線性表
//返回值:無
///////////////////////////////////////
voidClearList_Sq(SqList*L)
{
L->length=0;//將線性表的長度置為0
}
///////////////////////////////////////
//函數名:ListEmpty_Sq()
//參數:SqListL
//初始條件:線性表L已存在
//功能:判斷線性表是否為空
//返回值:空:TRUE
//非空:FALSE
///////////////////////////////////////
StatusListEmpty_Sq(SqListL)
{
if(L.length==0)
returnTRUE;
else
returnFALSE;
}
///////////////////////////////////////
//函數名:ListLength_Sq()
//參數:SqListL
//初始條件:線性表L已存在
//功能:返回線性表長度
//返回值:線性表長度(L.length)
///////////////////////////////////////
StatusListLength_Sq(SqListL)
{
return(L.length);
}
///////////////////////////////////////
//函數名:GetElem_Sq()
//參數:SqListL,inti,ElemType*e
//初始條件:線性表L已存在,1<=i<=ListLength(L)
//功能:用e返回線性表中第i個元素的值
//返回值:(i<1)||(i>ListLength(L)):ERROR
//1<=i<=ListLength(L):OK
///////////////////////////////////////
StatusGetElem_Sq(SqListL,inti,ElemType*e)
{
if(i<1||i>L.length)
returnERROR;//判斷i值是否合理,若不合理,返回ERROR
*e=L.elem[i-1];//數組中第i-1的單元存儲著線性表中第i個數據元素的內容
returnOK;
}
///////////////////////////////////////
//函數名:LocateElem_Sq()
//參數:L,e,compare(ElemType1,ElemType2)
//初始條件:線性表L已存在,compare()為數據元素判定函數
//功能:返回順序表L中第1個與e滿足關系compare()的數據元素的位序
//返回值:若在L中存在於e滿足關系compare()的元素:其位序
//若在L中不存在於e滿足關系compare()的元素:0
///////////////////////////////////////
intLocateElem_Sq(SqListL,e,compare(ElemType1,ElemType2))
{
inti=1;//i的初值為第1元素的位序
intp=L.elem;//p的初值為第1元素的存儲位置
while(i<=L.length&&!(*compare)(*p++,e))
++i;//依次進行判定
if(i<=L.length)
returni;//找到滿足判定條件的數據元素為第i個元素
else
return0;//該線性表中不存在滿足判定的數據元素
}
StatusPriorElem_Sq(SqListL,cur_e,&pre_e);
//見StatusNextElem_Sq(SqListL,cur_e,&next_e);
StatusNextElem_Sq(SqListL,cur_e,&next_e);
//我的思路是先用LocateElem_Sq()搜索cur_e的位序,
//再看是否大於等於length,
//若是,則返回OVERFLOW;否則返回後繼
//這樣也許有點麻煩?所以希望大家能夠補充方案
//bywangweinoo1
///////////////////////////////////////
//函數名:ListInsert_Sq()
//參數:SqList*L,inti,ElemTypee
//初始條件:線性表L已存在,1<=i<=ListLength(L)+1
//功能:在線性表中第i個數據元素之前插入數據元素e
//返回值:失敗:ERROR
//成功:OK
///////////////////////////////////////
StatusListInsert_Sq(SqList*L,inti,ElemTypee)
{
ElemType*j;
if(L->length==LIST_MAX_LENGTH)
returnERROR;//檢查是否有剩餘空間
if(i<1||i>L->length+1)
returnERROR;//檢查i值是否合理
//將線性表第i個元素之後的所有元素向後移動
for(j=L->length-1;j>=i-1;i++)
L->elem[j+1]=L->elem[j];
L->elem[i-1]=e;//將新元素的內容放入線性表的第i個位置,
L->length++;
returnOK;
}
///////////////////////////////////////
//函數名:ListDelete_Sq()
//參數:SqList*L,inti,Elemtype*e
//初始條件:線性表L已存在,1<=i<=ListLength(L)
//功能:將線性表L中第i個數據元素刪除
//返回值:失敗:ERROR
//成功:OK
///////////////////////////////////////
intListDelete_Sq(SqList*L,inti,Elemtype*e)
{
if(IsEmpty(L))
returnERROR;//檢測線性表是否為空
if(i<1||i>L->length)
returnERROR;//檢查i值是否合理
*e=L->elem[i-1];//將欲刪除的數據元素內容保留在e所指示的存儲單元中
//將線性表第i+1個元素之後的所有元素向前移動
for(j=i;j<=L->length-1;j++)L->elem[j-1]=L->elem[j];
L->length--;
returnOK;
}
//函數定義結束