【数据结构与算法】查找带头结点的单链表中倒数第k个结点的算法 C++实现(单链表+双指针法)
创始人
2024-11-15 04:32:26
0

设L是一个带头结点的单链表的表头指针,结点结构为(data,Link),在不改变链表的前提下,设计一个算法,查找链表中倒数第k个结点(k为正整数)。若查找成功,算法输出该结点的元素值,并返回1;否则,只返回0。


思路

双指针法,同时使用两个指针p1和p2。两个指针都指向链表的头节点。然后,指针p1开始遍历链表,每次前进一步。当p1前进到第k+1个节点时,指针p2开始从头节点开始遍历。这样,p1和p2始终保持k个节点的距离。当p1到达链表的末尾时,p2刚好位于链表的倒数第k个节点。

声明两个指针p1和p2,并将它们都初始化为指向链表的头节点。然后,使用一个for循环遍历链表。在每次迭代中,p1都向前移动一步。当p1移动了k步后,p2开始移动。

如果链表的长度小于k,那么p1将在p2开始移动之前到达链表的末尾。在这种情况下,函数返回ERROR,表示无法找到倒数第k个元素。

如果链表的长度大于或等于k,那么当p1到达链表的末尾时,p2将指向链表的倒数第k个元素。然后,函数打印p2指向的节点的数据,并返回OK,表示成功找到了倒数第k个元素。

由于每个节点只被访问一次,因此时间复杂度为 O ( n ) O(n) O(n),其中 n n n是链表的长度。这个算法只使用了常量级别的额外空间(两个指针p1和p2),所以空间复杂度为 O ( 1 ) O(1) O(1)。


代码

#include  #include  #define AUTHOR "HEX9CF" using namespace std; using Status = int; using ElemType = int;  const int N = 1e6 + 7; const int TRUE = 1; const int FALSE = 0; const int OK = 1; const int ERROR = 0; const int INFEASIBLE = -1; const int OVERFLOW = -2;  int n; ElemType a[N];  struct ListNode { 	ElemType data; 	ListNode *next; }; using LinkedList = ListNode *;  Status initList(LinkedList &first) { 	first = (ListNode *)malloc(sizeof(ListNode)); 	first->next = NULL; 	return OK; }  Status listInsert(LinkedList &L, int pos, ElemType e) { 	ListNode *p = L; 	for (int i = 0; p && i < pos; i++) { 		p = p->next; 	} 	if (!p) { 		return ERROR; 	} 	ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); 	newNode->data = e; 	newNode->next = p->next; 	p->next = newNode; 	return OK; }  ElemType getElem(LinkedList L, int pos) { 	ListNode *p = L->next; 	for (int i = 0; p && i < pos; i++) { 		p = p->next; 	} 	return p->data; }  ElemType getNthLastElem(LinkedList L, int k) { 	int i; 	ListNode *p1, *p2; 	p1 = p2 = L->next; 	for (i = 0; p1; i++) { 		p1 = p1->next; 		if (i > k) { 			p2 = p2->next; 		} 	} 	if (i < k) { 		return ERROR; 	} 	cout << p2->data << "\n"; 	return OK; }  int main() { 	cin >> n; 	for (int i = 0; i < n; i++) { 		cin >> a[i]; 	}  	int k; 	cin >> k;  	LinkedList L; 	initList(L);  	for (int i = 0; i < n; i++) { 		listInsert(L, i, a[i]); 	}  	// for (int i = 0; i < n; i++) { 	// 	cout << getElem(L, i) << " "; 	// } 	// cout << "\n";  	cout << getNthLastElem(L, k) << "\n"; 	return 0; }  

相关内容

热门资讯

微信炸金花购买房卡/微信斗牛如... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
炸金花微信群购买房卡/牛牛链接... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
拼三张从哪里买房卡/新海贝大厅... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
微信炸金花房卡一张多少钱/微信... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信链接炸金花房卡在哪买的/微... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信群链接炸金花房卡/微信里斗... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
怎么买炸金花房间链接房卡/微信... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信玩链接牛牛房卡/新人皇大厅... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享受...
拼三张房卡链接去哪里买/橘子大... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
微信玩炸金花怎么买房卡/欢乐游... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
炸金花房卡链接在哪买的/狂飙大... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
如何创建牛牛房间卡/牛至尊大厅... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
微信里上玩拼三张购买房卡/神牛... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信里面斗牛链接房卡/九酷大厅... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享受...
炸金花如何开好友房间房卡/微信... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信炸金花在哪里充值房卡/新天... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信里面拼三张房卡哪里买/新皇... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
微信群开牛牛房卡/新天地大厅牛... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受更...
微信打炸金花链接房卡怎么买/怎... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信玩炸金花房卡怎么买/开牛牛... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...