12.3 重新编写12.7,使用头和尾指针分别以一个单独的指针传递给函数,而不是作为一个节点的一部分
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
//指针fwd指向前一个节点,bwd指向后一个节点
typedef struct NODE {
struct NODE *fwd;
struct NODE *bwd;
int value;
} Node;
/*传入指向 头部和尾部节点的指针 的指针,四种情况
* 插入到表头,
* 插入到表尾,
* 插入到空表中,
* 插入到表中,前三个都需要修改headPtr或tailPtr指针
*/
int doubleLinklistInsert(Node **headPtr, Node **tailPtr, int value)
{
Node *this = *headPtr;
Node *newNode;
while( this != NULL && this -> value < value){
this = this -> fwd;
}
newNode = (Node *)malloc(sizeof(Node));
newNode -> value = value;
if(this == NULL){
//插入到表尾,或者空表中
if(this == *headPtr){
//插入到空表
*headPtr = newNode;
*tailPtr = newNode;
newNode -> fwd = NULL;
newNode -> bwd = NULL;
}else{
//插入到表尾
newNode -> fwd = NULL;
//原来的表尾元素为当前节点的前节点
newNode -> bwd = *tailPtr;
(*tailPtr) -> fwd = newNode;
//更新尾节点指针
*tailPtr = newNode;
}
}else{
//插入到表头,或者表中
if(this == *headPtr){
//插入到表头
newNode -> bwd = NULL;
//原来的表头变成第二个节点
newNode -> fwd = *headPtr;
(*headPtr) -> bwd = newNode;
//更新表头
*headPtr = newNode;
}else{
//插入到非空表中this位置的前面
newNode -> fwd = this;
newNode -> bwd = this -> bwd;
this -> bwd -> fwd = newNode;
this -> bwd = newNode;
}
}
return TRUE;
}
int main()
{
Node third;
Node second;
Node first;
third = (Node){NULL, &second, 4};
second = (Node){&third, &first, 2};
first = (Node){&second, NULL, 1};
Node *head = &first;
Node *tail = &third;
doubleLinklistInsert(&head, &tail, 35);
doubleLinklistInsert(&head, &tail, 3);
doubleLinklistInsert(&head, &tail, -10);
Node *rootPtr = head;
while(rootPtr != NULL){
printf("%d\t", rootPtr -> value);
rootPtr = rootPtr -> fwd;
}
return 0;
}
运行:

12.4 编写函数反序排列单链表所有节点。
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Node {
struct Node *next;
int value;
} Linklist;
Linklist *sll_reverse(Linklist *first)
{
if(first == NULL){
return NULL;
}
Linklist *current = first;
Linklist *next;
Linklist *pre;
Linklist *morePre = NULL;
while((next = current -> next) != NULL){
//循环移动当前指向的节点
pre = current;
current = next;
//修改前一节点的next指针为前前节点
pre -> next = morePre;
//移动前前节点morePre的指针
morePre = pre;
}
//如果为单个节点之间返回
if(current == first){
return first;
}else{
//修改最后一个节点的指针,作为头指针返回原来的最后一个节点的位置
current -> next = pre;
return current;
}
}
int main()
{
Linklist third = {NULL, 4};
Linklist second = {&third, 3};
Linklist first = {&second, 2};
Linklist *head = &first;
head = sll_reverse(head);
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
return 0;
}
运行:

12.5 编写程序,从一个单链表中删除一个节点,第一个参数为指向链表头部的指针的指针
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Node {
struct Node *next;
int value;
} Linklist;
//从first指向的链表中删除节点node
int sll_delete(Linklist **first, Linklist *node)
{
Linklist **ptr = first;
//Ptr为指向 next字段的 指针
while(*ptr != NULL && *ptr != node){
ptr = &((*ptr) -> next);
}
//如果没有找到
if(*ptr == NULL){
return FALSE;
}else{
//如果找到了,变更前节点指向
*ptr = (*ptr) -> next;
//释放节点内存
free(*ptr);
return FALSE;
}
}
int main()
{
Linklist third = {NULL, 3};
Linklist second = {&third, 2};
Linklist first = {&second, 1};
Linklist *headPtr = &first;
Linklist *head = headPtr;
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
printf("\n");
sll_delete(&headPtr, &second);
head = headPtr;
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
printf("\n");
sll_delete(&headPtr, &first);
head = headPtr;
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
printf("\n");
sll_delete(&headPtr, &third);
head = headPtr;
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
return 0;
}
运行:

12.6 双链表中移除节点,第一个参数为指向链表头部的指针,
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Node {
struct Node *next;
int value;
} Linklist;
//从first指向的链表中删除节点node
int sll_delete(Linklist *first, Linklist *node)
{
Linklist *pre = NULL;
Linklist *cur = first;
while(cur != NULL && cur != node){
pre = cur;
cur = cur -> next;
}
//如果没有找到
if(cur == NULL){
return FALSE;
}else if(cur == first){
//此时first是传值传入,只可以修改头指针指向的值,修改为第二个节点
*first = *(cur -> next);
free(node);
return TRUE;
}else{
pre -> next = cur -> next;
free(node);
return TRUE;
}
}
int main()
{
Linklist third = {NULL, 3};
Linklist second = {&third, 2};
Linklist first = {&second, 1};
Linklist *headPtr = &first;
Linklist *head = headPtr;
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
printf("\n");
sll_delete(headPtr, &second);
head = headPtr;
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
printf("\n");
sll_delete(headPtr, &first);
while (headPtr != NULL){
printf("%d\t", headPtr -> value);
headPtr = headPtr -> next;
}
printf("\n");
sll_delete(headPtr, &third);
head = headPtr;
while (head != NULL){
printf("%d\t", head -> value);
head = head -> next;
}
printf("\n");
return 0;
}
运行:

12.7 建立单词索引表
原文:http://www.cnblogs.com/yangxunwu1992/p/5851394.html