一.线性表的概述与理解
线性表是比较简单的一种数据结构,在上个学期学生管理系统的构建过程中,有做过一些初步的了解。线性表分为两种,一个是顺序储存的线性表,另外一个是链式储存的。
顺序储存的最大特点是在内存中的排列是连续的,数组也可以看成是顺序储存的线性表。链式储存的话,典型代表是链表,元素在内存中的排列是不连续的,准确地说在堆里面是不连续的。
二."临摹"与理解闵帆老师的顺序表代码
2.1 结构体
typedef struct SequentialList
{
int actualLength;
int data[LIST_MAX_LENGTH]; // The maximum length is fixed.
} * SequentialListPtr;
结构体内定义了线性表的长度,以及一个连续的数组;
2.2 打印顺序表
void outputList(SequentialListPtr paraList)
{
for (int i = 0; i < paraList->actualLength; i++)
{
printf("%d ", paraList->data[i]);
} // Of for i
printf("\r\n");
} // Of outputList
遍历元素进行打印
2.3 打印顺序表地址
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]);
}
2.4 创建线性表
SequentialListPtr sequentialListInit(int paraData[], int paraLength)
{
SequentialListPtr resultPtr = (SequentialListPtr)malloc(sizeof(struct SequentialList));
for (int i = 0; i < paraLength; i++)
{
resultPtr->data[i] = paraData[i];
} // Of for i
resultPtr->actualLength = paraLength;
return resultPtr;
} // Of sequentialListInit
malloc申请堆内存空间;将paraData数组中的内容转置于顺序表之中
2.5 线性表的插入
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 < 0)
{
printf("Cannot insert element: negative position unsupported.");
return;
} // Of if
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;
// Step 5. Update the length.
paraListPtr->actualLength++;
} // Of sequentialListInsert
首先对功能的合理性进行判断,一个是用来判断是否超过顺序表的最大限度,一个用来判断插入的位置是否合法。之后将元素插入,并且后移其后内容。
2.6 线性表插入的结果验证
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
通过打印的方式来进行验证。
2.7 线性表的删除
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
// Step 3. Update the length.
paraListPtr->actualLength--;
// Step 4. Return the value.
return resultValue;
} // Of sequentialListDelete
首先检查调用函数输入参数的合理性,之后将指定元素删除,并且将元素前移。结构体内Length--
2.8 线性表的删除结果测试
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
2.9 线性表元素的local
int locateElement(SequentialListPtr paraListPtr, int paraValue)
{
for (int i = 0; i < paraListPtr->actualLength; i++)
{
if (paraListPtr->data[i] == paraValue)
{
return i;
} // Of if
} // Of for i
return -1;
} // Of locateElement
2.10 线性表元素的GET
int getElement(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
return paraListPtr->data[paraPosition];
} // Of locateElement
通过输入位置,将指定位置的元素返回。
2.11 线性表元素的Clear
void clearList(SequentialListPtr paraListPtr)
{
paraListPtr->actualLength = 0;
} // Of clearList
将长度归0,使得一些函数的合理性判断return FALSE。