数据结构–1.1顺序表
第一步开始,临摹老师的代码。
#include <stdio.h>
#include <malloc.h>
#define LIST_MAX_LENGTH 10
/**
* Linear list of integers. The key is data.
*/
typedef struct SequentialList {
int actualLength;
int data[LIST_MAX_LENGTH];//The maximum length is fixed.
}*SequentialListPtr;
/**
* Output the list.
*/
void outputList(SequentialListPtr paraList){
for(int i=0;i<paraList->actualLength;i++)
{
printf("%d\n",paraList->data[i]);
}// Of for i
printf("\r\n");
}// Of outputList
/**
* Output the memeory for the list.
*/
void outputMemory(SequentialListPtr paraListPtr) {
printf("The address of the structure: %ld\r\n", paraListPtr);
printf("The address of actualLength: %ld\r\n", ¶ListPtr->actualLength);
printf("The address of data: %ld\r\n", ¶ListPtr->data);
printf("The address of actual data: %ld\r\n", ¶ListPtr->data[0]);
printf("The address of second data: %ld\r\n", ¶ListPtr->data[1]);
}// Of outputMemory
/**
* Initialize a sequential list. No error checking for this function.
* @param paraListPtr The pointer to the list. It must be a pointer to change the list.
* @param paraValues An int array storing all elements.
*/
SequentialListPtr sequentialListInit(int paraData[], int paraLength)
{
SequentialListPtr resultPtr = (SequentialList*)malloc(sizeof(SequentialList));
for(int i=0;i<paraLength;i++){
resultPtr->data[i]=paraData[i];
}//of for i;
resultPtr->actualLength = paraLength;
return resultPtr;
}
//of sequentialListInit
/**
* Insert an element into a sequential linear list.
* @param paraListPtr The pointer to the list. It must be a pointer to change the list.
* @param paraPosition The position, e.g., 0 stands for inserting at the first position.
* @param paraValue The value to be inserted.
*/
void sequentialListInsert(SequentialListPtr paraListPtr, int paraPosition, int paraValue) {
//step 1. space check.
if(paraListPtr->actualLength >=LIST_MAX_LENGTH){
printf("Cannot insert element: list full.\r\n");
return;
}//of if
//step 2. position check.
if(paraPosition > paraListPtr->actualLength){
printf("Cannot insert element: the position %d is bigger than the list length %d.\r\n", paraPosition, paraListPtr->actualLength);
return;
}//Of if
//step 3. move the remaining part.
for(int i=paraListPtr->actualLength;i>paraPosition;i--){
paraListPtr->data[i]=paraListPtr->data[i-1];
}//of for i
//step 4.insert.
paraListPtr->data[paraPosition]=paraValue;
//update the length.
paraListPtr->actualLength ++;
}//of sequentialListInsert
/**
* Test the insert function.
*/
void sequentialInsertTest() {
int i;
int tempArray[5] = {3, 5, 2, 7, 4};
printf("---- sequentialInsertTest begins. ----\r\n");
// Initialize.
SequentialListPtr tempList = sequentialListInit(tempArray, 5);
printf("After initialization, the list is: ");
outputList(tempList);
// Insert to the first.
printf("Now insert to the first, the list is: ");
sequentialListInsert(tempList, 0, 8);
outputList(tempList);
// Insert to the last.
printf("Now insert to the last, the list is: ");
sequentialListInsert(tempList, 6, 9);
outputList(tempList);
// Insert beyond the tail.
printf("Now insert beyond the tail. \r\n");
sequentialListInsert(tempList, 8, 9);
printf("The list is:");
outputList(tempList);
// Insert to position 3.
for (i = 0; i < 5; i ++) {
printf("Inserting %d.\r\n", (i + 10));
sequentialListInsert(tempList, 0, (i + 10));
outputList(tempList);
}//Of for i
printf("---- sequentialInsertTest ends. ----\r\n");
}// Of sequentialInsertTest
/**
* Delete an element from a sequential linear list.
* @param paraListPtr The pointer to the list. It must be a pointer to change the list.
* @param paraPosition The position, e.g., 0 stands for inserting at the first position.
* @return The deleted value.
*/
int sequentialListDelete(SequentialListPtr paraListPtr, int paraPosition){
//step 1.position check.
if(paraPosition<0){
printf("Invalid position: %d.\r\n", paraPosition);
return -1;
}//Of if
if (paraPosition >= paraListPtr->actualLength) {
printf("Cannot delete element: the position %d is beyond the list length %d.\r\n", paraPosition, paraListPtr->actualLength);
return -1;
}//Of if
//step 2. move the remaining part.
int resultValue = paraListPtr->data[paraPosition];
for (int i= paraPosition;i<paraListPtr->actualLength;i++){
paraListPtr->data[i]=paraListPtr->data[i+1];
}//of for i
//ste 3.update the length.
paraListPtr->actualLength--;
//step 4.Return the value.
return resultValue;
}
//of sequentialListDelete
/**
* Test the delete function.
*/
void sequentialDeleteTest() {
int tempArray[5] = {3, 5, 2, 7, 4};
printf("---- sequentialDeleteTest begins. ----\r\n");
// Initialize.
SequentialListPtr tempList = sequentialListInit(tempArray, 5);
printf("After initialization, the list is: ");
outputList(tempList);
// Delete the first.
printf("Now delete the first, the list is: ");
sequentialListDelete(tempList, 0);
outputList(tempList);
// Delete to the last.
printf("Now delete the last, the list is: ");
sequentialListDelete(tempList, 3);
outputList(tempList);
// Delete the second.
printf("Now delete the second, the list is: ");
sequentialListDelete(tempList, 1);
outputList(tempList);
// Delete the second.
printf("Now delete the 5th, the list is: ");
sequentialListDelete(tempList, 5);
outputList(tempList);
// Delete the second.
printf("Now delete the (-6)th, the list is: ");
sequentialListDelete(tempList, -6);
outputList(tempList);
printf("---- sequentialDeleteTest ends. ----\r\n");
outputMemory(tempList);
}// Of sequentialDeleteTest
int main() {
sequentialInsertTest();
sequentialDeleteTest();
}// Of main
这段代码包括了四个函数:创建,输出,插入以及删除。接下来是我自己对于这部分代码的一些分析。
首先是创建,由于老师定义的结构体里已经定义了我们将要处理的线性表的长度,所以创建就变得很简单,在这儿就不加以赘述了,一会我将会把自己优化过的代码(主要是针对长度的改变)附在此段文字之后。其次是输出,这个也没有什么好说的,一个简单的for循环就可以实现。
接下来是插入,插入部分我认为主要有两个主要问题:1.判断我们即将插入的位置是否存在于线性表中,2.如何插入。那么针对第一个问题,就需要我们进行全方面的考虑。可以看到程序给出了两个限制条件,一个是线性表此时的长度是否已经大于或等于我们所规定的最大长度,二是我们选择插入的位置是否大于此时线性表的长度。这两个都是很容易理解的,用简单的if-else就可以实现。那接下来该解决如何插入,我选择用一个简单的图来表示。
这个图向我们生动的展示了,当我们需要插入时,只需将插入位置及其之后的元素挨个向后移,然后将原来位置上的元素的数据变成我们想要插入的数据就好啦。具体代码的实现也只是用到基础的for循环。
那最后是删除。删除和插入一样,需要对我们想要进行处理的位置进行一个基础的判断,就是这个位置不能大于目前线性表的长度,当然也不能为负数。同时删除部分的思路也比较简单,就是让这个每个位置挨个往前挪,如下图:
当然,我们也可以先用一个变量将我们选择删除的那个元素的值保存起来,再进行删除操作。
至此,对于老师代码的临摹就结束了。
接下来是我自己写的一段代码:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct Arr{
int *pBase;//存储数组第一个元素的地址
int len;//数组所能容纳的最大元素的个数
int cnt;//当前数组有效元素的个数
};
void init(struct Arr *pArr,int lenth);//初始化
bool insert(struct Arr *pArr,int pos,int val);//插入
bool append(struct Arr *pArr,int val);
bool delete_arr(struct Arr *pArr,int pos,int *pVal);//删除
bool get();
bool is_empty(struct Arr *pArr);//判断空
bool is_full(struct Arr *pArr);//判断满
bool sort(struct Arr *pArr);//排序
void show(struct Arr *pArr);//输出
void search(struct Arr *pArr,int pos);//查找
void clear(struct Arr *pArr);//清除
int located(struct Arr *pArr,int pos);//定位
int main(void)
{
struct Arr arr;
int val,VAL;
int pos,POS;
init(&arr,6); //用指针改变值
append(&arr,1);
append(&arr,2);
append(&arr,3);
append(&arr,4);
show(&arr);
if(delete_arr(&arr,1,&val))
{
printf("删除成功!\n");
printf("您删除的元素是:%d\n",val);
}
else{
printf("删除失败!\n");
}
printf("删除之后为:\n");
show(&arr);
printf("请依次输入您想插入的位置以及元素:");
scanf("%d %d",&pos,&val);
if(insert(&arr,pos,val))
{
printf("插入成功!插入的位置为:%d,插入的元素为:%d",pos,val);
printf("插入之后为:\n");
show(&arr);
}
printf("请输入您想查找的元素位置:");
scanf("%d",&POS);
printf("该位置的元素为:");
search(&arr,POS);
printf("\n请输入您想查找的元素:");
scanf("%d",&VAL);
printf("该元素的位置为:%d",located(&arr,VAL));
sort(&arr);
printf("\n排序之后为:\n");
show(&arr);
clear(&arr);
return 0;
}
void init(struct Arr *pArr,int lenth)//初始化
{
pArr->pBase = (int *)malloc(sizeof(int)*lenth);
if(NULL==pArr->pBase)//检测动态内存是否分配成功
{
printf("动态内存分配失败!\n");
exit(-1);//终止整个程序
}
else
{
pArr->len = lenth;
pArr->cnt = 0;
}
return;
}
bool is_full(struct Arr *pArr)
{
if(pArr->len==pArr->cnt)
{
return true;
}
else
{
return false;
}
}
bool is_empty(struct Arr *pArr)
{
if(pArr->cnt==0)
{
return true;
}
else
return false;
}
void show(struct Arr *pArr)
{
if( is_empty(pArr))
{
printf("数组为空!\n");
}
else
{
for(int i=0;i<pArr->cnt;++i)
{
printf("%d ",pArr->pBase[i]);
}
printf("\n");
}
}
bool append(struct Arr *pArr,int val)//追加
{
if(is_full(pArr))//判断数组是否是满的
{
return false;
}//不满时追加 ,cnt的值是要放入元素的下标
else
{
pArr->pBase[pArr->cnt]=val;
(pArr->cnt)++; //cnt是当前有效元素的个数
return true;
}
}
bool insert(struct Arr *pArr,int pos,int val)//插入
{
int i;
if(is_full(pArr))
{
return false;
}
//判断pos的值是否可以插入
if(pos<1||pos>pArr->cnt+1)
{
return false;
}
//用一个for循环,将原有的元素从最后一个有效值开始往后移
for(i=pArr->cnt-1;i>=pos-1;--i)
{
pArr->pBase[i+1]=pArr->pBase[i];
}
pArr->pBase[pos-1]=val;
(pArr->cnt)++;
return true;
}
bool delete_arr(struct Arr *pArr,int pos,int *pVal)
{
int i;
if(is_empty(pArr))
{
return false;
}
if(pos<1||pos>pArr->cnt)
{
return false;
}
*pVal=pArr->pBase[pos-1];
for(i=pos;i<pArr->cnt;++i)
{
pArr->pBase[i-1]=pArr->pBase[i];
}
pArr->cnt--;
return true;
}
void search(struct Arr *pArr,int pos)
{
int i;
if(pos>pArr->cnt )
{
printf("查找失败!\n");
}
else
{
printf("%d",pArr->pBase [pos-1]);
}
}
bool sort(struct Arr *pArr)
{
int i;
int j;
int t;
for(i=0;i<pArr->cnt-1;i++)
{
for(j=i+1;j<pArr->cnt;j++)
{
if(pArr->pBase[i]>pArr->pBase[j])
{
t=pArr->pBase[i];
pArr->pBase[i]=pArr->pBase[j];
pArr->pBase[j]=t;
}
}
}
}
int located(struct Arr *pArr,int VAL)
{
int location;
int i=0;
while(pArr->pBase [i]!=VAL)
{
i++;
}
location=i+1;
return location;
}
void clear(struct Arr *pArr)
{
pArr->cnt =0;
return ;
}
运行结果如下: