重命名一下,后面定义变量和整体的修改更方便
typedef int SLNodeDataType;
typedef struct ListNode {
SLNodeDataType data;
struct ListNode* next;
} SLNode;
打印链表,传头指针
void SLNodePrint(SLNode* phead) {
//SLNode* cur = phead;
while (phead!= NULL)
{
printf("%d->", phead->data);
phead = phead->next;
}
printf("NULL\n");
}
//创建结点
SLNode* CreatSLNode(SLNodeDataType x) {
SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
if (newnode == NULL)//判断是否开辟成功
{
printf("malloc fail\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
//尾插
void SLNodePushBack(SLNode** pphead, SLNodeDataType x) {
SLNode* newnode = CreatSLNode(x);
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
SLNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
该函数修改了结构体,传递一个指针的地址,用一个二级指针接收。如果是一个一级指针接收一个一级指针,这只是临时拷贝。对该指针修改并不会修改链表。
//头插
void SLNodePushFront(SLNode** pphead, SLNodeDataType x) {
SLNode* newnode = CreatSLNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
//尾删
void SLNodePopBack(SLNode** pphead)
{
assert(*pphead != NULL);
if ((*pphead)->next)//两个结点以上
{
SLNode* tail = *pphead;
while (tail->next->next)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
//SLNode* tail = *pphead;
//SLNode* pre = tail;
//while (tail->next)
//{
// pre = tail;
// tail = tail->next;
//}
//free(tail);
//tail = NULL;
//pre->next = NULL;
free(tail);野指针问题,将最后一个结点释放,倒数第二个结点还是指向倒数第一个结点,
tail->next = NULL//需要把倒数第二个结点置空
// }
else//一个结点
{
free(*pphead);
*pphead = NULL;
}
}
//头删
void SLNodePopFront(SLNode** pphead)
{
assert(*pphead != NULL);
SLNode* next = (*pphead)->next;
free(*pphead);
*pphead = next;//不能先释放*pphead;因为释放会导致找不到下一个结点的地址
}
//查找
SLNode* SLNodeFind(SLNode* phead, SLNodeDataType x)
{
while (phead)
{
if (phead->data == x)
{
return phead;
}
else
{
phead = phead->next;
}
}
return NULL;
}
//查找的两种用法
//多个值时的查找
/*SLNode* pos = SLNodeFind(head,2);
int i = 1;
while (pos)
{
printf("第%d个结点:%p->%d\n", i++, pos, pos->data);
pos = SLNodeFind(pos->next, 2);
}*/
//修改 2->20
SLNode* pos = SLNodeFind(head, 2);
/*while (pos)
{
pos->data = 20;
pos = SLNodeFind(pos->next, 2);
}*/
//if (pos)
//{
// pos->data = 20;
//}
void SLNodeInserpre(SLNode** pphead, SLNode* pos, SLNodeDataType x)
{
SLNode* newnode = CreatSLNode(x);
//pos前插入
//if (*pphead == pos)//假如pos指向第一个结点
//{
// newnode->next = *pphead;
// *pphead = newnode;
//}
//else
//{
// SLNode* prepos = *pphead;
// while (prepos->next!=pos)
// {
// prepos = prepos->next;
// }
// prepos->next = newnode;
// newnode->next = pos;
//}
void SLNodeInseraft(SLNode** pphead, SLNode* pos, SLNodeDataType x)
//pos后插入,更简单,效率更高
newnode->next = pos->next;
pos->next = newnode;
//删除
void SLNodeErase(SLNode** pphead, SLNode* pos)
{
if (*pphead = pos)
{
/**pphead = pos->next;
free(pos)*/
SLNodePopFront(pphead);
}
else
{
SLNode* prepos = *pphead;
while (prepos->next != pos)
{
prepos = prepos->next;
}
prepos->next = pos->next;
free(pos);
}
}
//销毁
void SLNodeDestory(SLNode** pphead)
{
assert(pphead);
SLNode* cur = *pphead;
while (cur)
{
SLNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
补充一点,该链表不含虚拟头节点,所以在进行插入和删除操作的时候,需要传入二级指针,因为当链表为空的时候,需要修改传入的结点。如果是含有虚拟头节点的链表,不需要修改,(即不需要传入二级指针),只需要将虚拟头节点的指针域指向传入的结点即可。
python伪代码:
class SequentialList:
def __init__(self):
"""初始化顺序表"""
self.capacity = 10 # 顺序表的容量
self.size = 0 # 顺序表的大小
self.elements = [0] * self.capacity # 一个列表,储存顺序表中的元素,初始化全为0
def __del__(self):
"""销毁顺序表"""
del self.elements # 删除对象的element属性,可以释放该属性所占用的内存
def ssize(self):
"""获取顺序表元素的个数"""
return self.size
def is_empty(self):
"""判断顺序表是否为空"""
return self.size == 0
def resize(self):
"""顺序表扩容"""
new_capacity = self.capacity * 2
new_elements = [0] * new_capacity
for i in range(self.size):
new_elements[i] = self.elements[i]
self.capacity = new_capacity
self.elements = new_elements
def insert(self, index, element):
"""在指定的index插入element"""
if index < 0 or index > self.size:
raise ValueError("Invalid index")
if self.size == self.capacity:
self.resize()
for i in range(self.size - 1, index - 1, -1):
self.elements[i] = self.elements[i - 1]
self.elements[index] = element
self.size += 1
def remove(self, index):
"""删除index处的元素"""
if index < 0 or index > self.size:
raise ValueError("Invalid index")
for i in range(index + 1, self.size):
self.elements[i - 1] = self.elements[i]
self.size -= 1
def get(self, index):
"""获取index处的元素"""
if index < 0 or index > self.size:
raise ValueError("Invalid index")
return self.elements[index]
def find_index(self, element):
"""查找element的下标"""
for i in range(self.size):
if self.elements[i] == element:
return i
return -1 # 没找到
def __iter__(self):
"""迭代顺序表中的元素"""
for i in range(self.size):
yield self.elements[i]
def __str__(self):
"""打印顺序表"""
return "Sequential List:" + str(self.elements[:self.size])