链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中指针的连接次序实现的。 在8中链表中,常用的有两种:无头单向不循环链表和带头循环双向链表。 首先,无头单项不循环链表的结构简单,但是一般不用来存储数据,实际中更多的是作为其他数据结构的子结构,比如:哈希桶、图的邻接表等; 下面是其增删查改等操作的代码实现:
typedef int SLDataType;
/ 结点(数据和指向下一个结点的指针,其类型为结点指针)
typedef struct SListNode{
SLDataType _data;
struct SListNode* _next;
} SListNode;
/ 单链表(链表的起点:不是头结点,头结点不占空间)
typedef struct SList{
SListNode* _head;
} SList;
void SListInit ( SList* plist) {
assert ( plist) ;
plist-> _head = NULL ;
}
/ 当链表的起点存在时就要开始删除( 要记录每次删除结点的下一个结点)
void SListDestory ( SList* plist) {
assert ( plist) ;
while ( plist-> _head) {
SListNode* tNode = plist-> _head-> _next;
free ( plist-> _head) ;
plist-> _head = tNode;
}
}
SListNode* BuySListNode ( SLDataType x) {
SListNode* newNode = ( SListNode* ) malloc ( sizeof ( SListNode) ) ;
assert ( newNode) ;
newNode-> _data = x;
newNode-> _next = NULL ;
return newNode;
}
/ 链表头插(如果当前链表不为空,就把新结点当做链表的起点,
/ 原链表的起点就变成了链表的第二个结点)
void SListPushFront ( SList* plist, SLDataType x) {
assert ( plist) ;
SListNode* newNode = BuySListNode ( x) ;
assert ( newNode) ;
if ( plist-> _head == NULL ) {
plist-> _head = newNode;
return ;
}
else {
newNode-> _next = plist-> _head;
plist-> _head = newNode;
}
}
void SListPopFront ( SList* plist) {
assert ( plist) ;
SListNode* tNode = plist-> _head-> _next;
free ( plist-> _head) ;
plist-> _head = tNode;
}
void SListPushBack ( SList* plist, SLDataType x) {
assert ( plist) ;
SListNode* newNode = BuySListNode ( x) ;
assert ( newNode) ;
if ( plist-> _head == NULL ) {
plist-> _head = newNode;
}
else {
SListNode* tail = plist-> _head;
while ( tail-> _next) {
tail = tail-> _next;
}
tail-> _next = newNode;
}
}
/ 尾删:有一个结点;
/ 有多个结点:要记录倒数第二个结点的位置
void SListPopBack ( SList* plist) {
assert ( plist-> _head) ;
SListNode* tail = plist-> _head;
if ( tail-> _next == NULL ) {
free ( tail) ;
plist-> _head = NULL ;
}
while ( tail-> _next-> _next!= NULL ) {
tail = tail-> _next;
}
free ( tail-> _next) ;
tail-> _next = NULL ;
}
SListNode* SListFind ( SList* plist, SLDataType x) {
assert ( plist) ;
SListNode* tNode = plist-> _head;
while ( tNode != NULL ) {
if ( tNode-> _data != x) {
tNode = tNode-> _next;
}
else {
return tNode;
}
}
return - 1 ;
}
/ 在pos的后面插入结点( pos位置不存在;pos在头上;pos在后边)
void SListInsertAfter ( SList* plist, SListNode* pos, SLDataType x) {
assert ( plist) ;
SListNode* newNode = BuySListNode ( x) ;
assert ( newNode) ;
if ( pos == - 1 ) {
return - 1 ;
}
else if ( pos == plist-> _head) {
SListPushFront ( plist, x) ;
}
else {
SListNode* tNode = plist-> _head-> _next;
while ( tNode != pos) {
tNode = tNode-> _next;
}
tNode = pos-> _next;
pos-> _next = newNode;
newNode-> _next = tNode;
}
}
/ 在pos的后面删除结点
void SListEraseAfter ( SList* plist, SListNode* pos) {
assert ( plist) ;
if ( pos == - 1 ) {
return - 1 ;
}
else if ( pos == plist-> _head) {
SListPopFront ( plist) ;
}
else {
SListNode* tNode = plist-> _head-> _next;
while ( tNode != pos) {
tNode = tNode-> _next;
}
SListNode* cur = tNode-> _next;
SListNode* tail = tNode-> _next-> _next;
free ( cur) ;
tNode-> _next = tail;
}
}
/ 删除链表中的值为X的元素
void SListRemove ( SList* plist, SLDataType x) {
assert ( plist) ;
SListNode* bNode = plist-> _head;
if ( bNode-> _data == x) {
SListNode* cur = bNode;
free ( bNode) ;
cur-> _next = plist-> _head;
return ;
}
else {
SListNode* tNode = plist-> _head-> _next;
while ( tNode-> _data != x) {
bNode = bNode-> _next;
tNode = tNode-> _next;
}
SListNode* eNode = tNode-> _next;
free ( tNode) ;
bNode-> _next = eNode;
}
}
/ 打印的时候,不能直接用plist-> _head直接遍历,会改变头指针的位置。
void SListPrint ( SList* plist) {
assert ( plist) ;
SListNode* head = plist-> _head;
while ( head-> _next) {
printf ( "%d->" , head-> _data) ;
head = head-> _next;
}
printf ( "%d\n" , head-> _data) ;
}