1.C语言是如何构造出链表的?
(1)链表中的结点结构
(2)链表的结构图
(3)C语言初始化链表
struct ListNode {
int value; //数据
struct ListNode *next; //继结点指针
};
struct ListNode* initLink() {
int i;
//1、创建头指针
struct ListNode* head = NULL;
//2、创建头结点
struct ListNode* temp = (struct ListNode*)malloc(sizeof(struct ListNode));
temp->val = 0;
temp->next = NULL;
//头指针指向头结点
head = temp;
//3、每创建一个结点,都令其直接前驱结点的指针指向它
for (i = 1; i < 5; i++) {
//创建一个结点
struct ListNode* a = (struct ListNode*)malloc(sizeof(struct ListNode));
a->val = i;
a->next = NULL;
//每次 temp 指向的结点就是 a 的直接前驱结点
temp->next = a;
//temp指向下一个结点(也就是a),为下次添加结点做准备
temp = temp->next;
}
return p;
}
int main() {
struct ListNode* p = NULL;
printf("初始化链表为:\n");
//创建链表{1,2,3,4}
p = initLink();
return 0;
}
遍历链表
void basicLinkList(struct ListNode* p){
struct ListNode* temp = p;
while(temp){
struct ListNode* f = temp;
printf("%d ",temp->value);
temp = temp->next;
free(f);
}
printf("\n")
}
Java版
java的结点资源不需要手动释放,jvm会自动对无引用的对象进行gc回收
public class LinkNodeListDemo {
private LinkNode headNode;//头指针
public LinkNode getHeadNode() {
return headNode;
}
public void setHeadNode(LinkNode headNode) {
this.headNode = headNode;
}
public LinkNodeListDemo(int size) {
LinkNode tempNode = new LinkNode(0, null);
headNode = tempNode;
for (int i = 1; i < size; i++) {
LinkNode childNode = new LinkNode(i, null);
tempNode.setNext(childNode);
tempNode = tempNode.getNext();
}
}
public static void main(String[] args) {
LinkNodeListDemo linkNodeListDemo = new LinkNodeListDemo(10);
LinkNode tempNode = linkNodeListDemo.headNode;//定义临时指针
while (tempNode != null) {
System.out.println(tempNode.getValue());
tempNode = tempNode.getNext();
}
}
}
class LinkNode {
private int value;
private LinkNode next;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public LinkNode getNext() {
return next;
}
public void setNext(LinkNode next) {
this.next = next;
}
public LinkNode(int value, LinkNode next) {
this.value = value;
this.next = next;
}
}
2.链表增加元素,首部、中间和尾部
首部:
中部:
尾部:
C语言实现
struct ListNode* insertNode(struct ListNode* head, struct ListNode* nodeInsert, int position) {
if (head == NULL) {
// 这里可以认为待插入的节点就是链表的头节点,也可以抛出不能插入的异常
return nodeInsert;
}
int size = getLength(head);
if (position > size + 1 || position < 1) {
printf("位置参数越界");
return head;
}
// 插入节点到头部
if (position == 1) {
nodeInsert->next = head;
head = nodeInsert;
return head;
}
struct ListNode* pNode = head;
int count = 1;
// 遍历链表,找到插入位置的前一个节点
while (count < position - 1) {
pNode = pNode->next;
count++;
}
nodeInsert->next = pNode->next;
pNode->next = nodeInsert;
return head;
}
void testInsert(){
struct ListNode* head = NULL;
struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->val=1;
// 插入第一个元素
head=insertNode(head,node,1);
printList(head);
// 插入第二个元素,因为前面至于一个元素,这里就是在尾部插入了
node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->val=3;
head=insertNode(head,node,2);
printList(head);
// 插入第二个元素,后面有个三,所以这里就是中间位置插入了
node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->val=2;
head=insertNode(head,node,2);
printList(head);
}
Java实现
public void addNode(LinkNode headNode, LinkNode addNode, int position) {
if (headNode == null) {
return;
}
int nodeLength = getLinkNodeLength(headNode);
if (position > nodeLength + 1 || position < 1) {
System.out.println("参数位置越界");
return;
}
if (position == 1) {
addNode.setNext(headNode);
headNode = addNode;
this.headNode= headNode;
return;
}
int count = 1;
LinkNode tempNode = headNode;
while (count < position - 1) {
tempNode = tempNode.getNext();
count++;
}
addNode.setNext(tempNode.getNext());
tempNode.setNext(addNode);
this.headNode= headNode;
}
public static void main(String[] args) {
LinkNodeListDemo linkNodeListDemo = new LinkNodeListDemo(10);
LinkNode addNode1 = new LinkNode(100, null);
linkNodeListDemo.addNode(linkNodeListDemo.headNode, addNode1, 5);
LinkNode addNode2 = new LinkNode(100, null);
linkNodeListDemo.addNode(linkNodeListDemo.headNode, addNode2, 10);
LinkNode addNode3 = new LinkNode(100, null);
linkNodeListDemo.addNode(linkNodeListDemo.headNode, addNode3, 1);
LinkNode tempNode = linkNodeListDemo.headNode;
while (tempNode != null) {
System.out.println(tempNode.getValue());
tempNode = tempNode.getNext();
}
}
3.链表删除元素,首部、中间和尾部
首部
尾部
中间
C语言实现
struct ListNode* deleteNode(struct ListNode*head, int position) {
if (head == NULL) {
return NULL;
}
int size = getLength(head);
if (position > size || position < 1) {
printf("输入的参数有误\n");
return head;
}
if (position == 1) {
return head->next;
} else {
struct ListNode* preNode = head;
int count = 1;
while (count < position - 1) {
preNode = preNode->next;
count++;
}
struct ListNode*curNode = preNode->next;
preNode->next = curNode->next;
free(curNode);
return head;
}
}
void testDelete(){
struct ListNode* p = NULL;
printf("create list: \t\n");
//创建链表0~9
p = initLink();
printList(p);
// 删除第一个元素0
p= deleteNode(p,1);
printList(p);
//删除中间元素
p= deleteNode(p,5);
printList(p);
//删除末尾元素9
p= deleteNode(p,8);
printList(p);
}
Java实现
public void deleteNode(int position) {
if (headNode == null) {
return;
}
int nodeLength = getLinkNodeLength(headNode);
if (position > nodeLength + 1 || position < 1) {
System.out.println("参数位置越界");
return;
}
if (position == 1) {
headNode.setNext(headNode.getNext().getNext());
return;
}
LinkNode tempNode = headNode;
int count = 1;
while (count < position - 1) {
tempNode = tempNode.getNext();
count++;
}
tempNode.setNext(tempNode.getNext().getNext());
}
public static void main(String[] args) {
LinkNodeListDemo linkNodeListDemo = new LinkNodeListDemo(10);
linkNodeListDemo.deleteNode(10);
linkNodeListDemo.deleteNode(1);
linkNodeListDemo.deleteNode(5);
LinkNode tempNode = linkNodeListDemo.headNode;
while (tempNode != null) {
System.out.println(tempNode.getValue());
tempNode = tempNode.getNext();
}
}