1.创建一个链表
创建连接的第一步就是创建一个包含数据和指针的结构体,其中数据可以是任何类型的,指针类型,是当前结构体类型的,如下图,创建一个包含一个整形的数据 (data) 和一个本身结构类型的指针 (next指针)。如下示
struct nodeList { int data; struct nodeList *next; }; 开始创建一个链表,在这里用最简单的一种方式创建,通过for 循环创建链表,更新链表的头结点和尾节点.详细步骤
创建一个空的头节点和尾节点
开始for循环,每一次都创建一个node,通过malloc进行创建
如果当前节点是空的,将第一次创建的node 赋值给头节点,并且刷新data数据(更新当前节点)
如果当前节点不是空的,将当前节点(尾节点)的next 指针指向当前创建的node,并且刷新data数据(更新当前节点)
tips:更新当前节点就是,将创建的节点赋值给(当前节点也就是尾节点)
struct nodeList* createLinkList(){ //头结点 struct nodeList *head = NULL; //尾节点,当前节点 struct nodeList *currentNode = NULL;
for (int i = 0; i < 5; i++) {
//创建一个节点
struct nodeList *node = (struct nodeList*)malloc(sizeof(struct nodeList));
node->data = i;
if (head ==NULL){
//赋值头结点
head = node;
} else {
//尾节点next指针指向创建的节点
currentNode->next = node;
}
//更新当前节点
currentNode = node;
}
return head;
} 2.打印一个链表
打印一个链表就比较简单了,找到当前节点,调用 node->data 进行数据的打印即可,注意找到当前节点,如下图
void printNodeList(struct nodeList*node){ struct nodeList *temp = node; while (temp != NULL) { //打印当前节点 std::cout << temp->data << std::endl; temp = temp->next; } } 3.单链表反转
单链表反转的步骤
定义一个遍历指针,初始化为头结点
定义一个反转链表的头部
开始进行遍历
当前结点的next指向新链表头部 更改链表头部为当前结点 移动遍历的指针 struct nodeList *reverseLinkList(struct nodeList *node){ // 定义遍历指针,初始化为头结点 struct nodeList *p = node; // 反转后的链表头部 struct nodeList *newH = NULL; // 遍历链表 while (p != NULL) { // 记录下一个结点 struct nodeList *temp = p->next; // 当前结点的next指向新链表头部 p->next = newH; // 更改新链表头部为当前结点 newH = p; // 移动p指针 p = temp; } // 返回反转后的链表头结点 return newH; } 4.倒数第K个链表结点
第一种方法,普通计算,让倒着计算,变成正着计算,例如 // 1 2 3 4 5 6 倒数第二个 就是 5 k=2 。正数:// 6-2+1=5 正数第五个就是要求的数。
struct nodeList *backwardsGetLinkNode(struct nodeList *node,unsigned int k){ // 1 2 3 4 5 6 倒数第二个 就是 5 k=2 // 6-2+1=5 正数第五个就是要求的数
struct nodeList *countNode = node;
int count = 0;
//链表结点个数
while (countNode != NULL){
count ++;
countNode = countNode->next;
}
//算出正着多少位
int number = count - k + 1;
struct nodeList *getNode = node;
struct nodeList *inNode = NULL;
int total= 0;
//找到对应位数的结点
while (getNode != NULL) {
total ++;
if (number == total){
inNode = getNode;
return inNode;
}
getNode = getNode->next;
}
} 第二种方法就相对简单一些
定义两个指针,前指针指向K-1的位置 后指针指向链表头部 同时移动前后指针,当前指针指向链表的最后一个 那么对应的后指针指向的就是倒数第K的结点 struct nodeList *backwardsDoublePointerGetLinkNode(struct nodeList *node,unsigned int k){ //前指针 指向K-1的位置 struct nodeList *pHead = node; //后指针, 指向链表的头部 struct nodeList *pBehind = node; for (int i = 0; i < k-1; ++i) { pHead = pHead->next; }
//前指针和后指针同时移动,当前指针指向最后,后指针指向倒数k个
while (pHead->next != NULL){
pHead = pHead->next;
pBehind = pBehind->next;
}
return pBehind;
} 5.链表中环的入口结点
判断链表中是否有环需要经过以下这几个步骤。这张图可以看到大致的结果 ? ws4.sinaimg.cn/large/006tN… ? ws4.sinaimg.cn/large/006tN…
链表中是否有环 用两个指针,一个慢指针和一个快指针指向头部 慢指针一步一步的走,快指针两步两步的走。 当两个指针重合的时候,证明这个链表一定有环 环的结点是几个 当两个指针重合判断出有环的时候 让慢指针重新走到当前的位置就可以确定环的结点有几个 怎么确定环的入口结点 还是创建两个指针,指针1和指针2 指针1指向链表的头部,指针2指向头部到环结点个数的结点 指针1和指针2同时前进 6.删除链表中重复的结点
例如这种链表1->2->3->3->4->4->5 处理后为 1->2->5,说起来的就很简单了,删除重复的结点就好了,但是实现的时候,确需要。。
先创建记录当前结点前的最晚访问过的不重复的结点pPre 创建指向当前结点的pCur 创建当前结点的next结点pNext 如果当前的结点和next结点相同那么这些结点,需要删除,重新更新pCur和pNext结点,如果不相同直接更新pCur和pNext结点 tips,如果从第一个结点就是重复的话,需要特殊处理一下