1. 引言
本文主要讲解一些常见的关于链表的算法和面试题。
2. 单链表的反序(不带头结点)
/* 不带头结点的单链表逆转 */ #include "ds.h" using namespace std; typedef int ElemType; typedef struct LNode{ ElemType data; struct LNode *next; }LNode, *LinkList; void InitList(LinkList &L); void TailCreList(LinkList &L, int n); void ReverseList(LinkList &L); void TraverseList(LinkList L); void InitList(LinkList &L) { L = NULL; } void TailCreList(LinkList &L, int n) { LinkList p, tail, s; int i; if (0 > n) return; tail = L; printf("please input %d number:", n); for (i = 1; i <= n; i++) { s = (LinkList)malloc(sizeof(LNode)); scanf("%d", &(s->data)); if (1 == i) { s->next = tail; L = tail = s; } else { tail->next = s; tail = tail->next; } } tail->next = NULL; } void ReverseList(LinkList &L) { LinkList pre_pre, pre, cur; // 链表为空和只有一个元素时不用逆转 if (NULL == L || NULL == L->next) return; cur = L; pre = NULL; // 从第二个元素开始逆转, while (cur->next) { // pre_pre, pre, cur 向前移动 pre_pre = pre; pre = cur; cur = cur->next; // 开始逆转 pre->next = pre_pre; } // 将最后一个结点指向其前驱 cur->next = pre; // 头指针指向最后一个结点L L = cur; } void TraverseList(LinkList L) { LinkList p = L; while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); } int main() { LinkList L; InitList(L); TailCreList(L, 5); TraverseList(L); ReverseList(L); TraverseList(L); }
3. 输入一个单向链表,输出该链表中倒数第 k 个结点。
// 输入一个单向链表,输出该链表中倒数第 k 个结点。 #include "ds.h" using namespace std; typedef int ElemType; typedef struct LNode{ ElemType data; struct LNode *next; }LNode, *LinkList; void InitList(LinkList &L); void TailCreList(LinkList &L, int n); int OutputLast_K(LinkList L, int k); void TraverseList(LinkList L); void InitList(LinkList &L) { L = NULL; } void TailCreList(LinkList &L, int n) { LinkList p, tail, s; int i; if (0 > n) return; tail = L; printf("please input %d number:", n); for (i = 1; i <= n; i++) { s = (LinkList)malloc(sizeof(LNode)); scanf("%d", &(s->data)); if (1 == i) { s->next = tail; L = tail = s; } else { tail->next = s; tail = tail->next; } } tail->next = NULL; } /* 返回值说明: 0 -> 输出成功 -1 -> 链表为空或k<1 -2 -> 链表长度小于k */ int OutputLast_K(LinkList L, int k) { LinkList p_k = L, p_add_k = L; int i = 0; // 链表为空和k<1 if (NULL == L || k < 1) { if (k < 1) printf("k < 1 \n"); return -1; } // 当p_add_k到链表尾部时,p_k到倒数第k个结点处 while (p_add_k) { if (i < k) { i++; } else { p_k = p_k->next; } p_add_k = p_add_k->next; } // 链表长度大于等于K if (i == k) { while (p_k) { printf("%d ", p_k->data); p_k = p_k->next; } printf("\n"); } // 链表长度小于K else { printf("List L less %d element.\n", k); return -2; } return 0; } void TraverseList(LinkList L) { LinkList p = L; while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); } int main() { LinkList L; InitList(L); TailCreList(L, 5); TraverseList(L); for (int i = 0; i < 8; i++ ) OutputLast_K(L, i); }